summaryrefslogtreecommitdiff
path: root/os/mpc/spi.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/spi.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/spi.c')
-rw-r--r--os/mpc/spi.c243
1 files changed, 0 insertions, 243 deletions
diff --git a/os/mpc/spi.c b/os/mpc/spi.c
deleted file mode 100644
index ce662533..00000000
--- a/os/mpc/spi.c
+++ /dev/null
@@ -1,243 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-/*
- * basic read/write interface to mpc8xx Serial Peripheral Interface;
- * used by devtouch.c and devspi.c
- */
-
-typedef struct Ctlr Ctlr;
-
-enum {
- /* spi-specific BD flags */
- BDContin= 1<<9, /* continuous mode */
- RxeOV= 1<<1, /* overrun */
- TxeUN= 1<<1, /* underflow */
- BDme= 1<<0, /* multimaster error */
- BDrxerr= RxeOV|BDme,
- BDtxerr= TxeUN|BDme,
-
- /* spmod */
- MLoop= 1<<14, /* loopback mode */
- MClockInv= 1<<13, /* inactive state of SPICLK is high */
- MClockPhs= 1<<12, /* SPCLK starts toggling at beginning of transfer */
- MDiv16= 1<<11, /* use BRGCLK/16 as input to SPI baud rate */
- MRev= 1<<10, /* normal operation */
- MMaster= 1<<9,
- MSlave= 0<<9,
- MEnable= 1<<8,
- /* LEN, PS fields */
-
- /* spcom */
- STR= 1<<7, /* start transmit */
-
- /* spie */
- MME = 1<<5,
- TXE = 1<<4,
- BSY = 1<<2,
- TXB = 1<<1,
- RXB = 1<<0,
-
- /* port B bits */
- SPIMISO = IBIT(28), /* master mode input */
- SPIMOSI = IBIT(29), /* master mode output */
- SPICLK = IBIT(30),
-
- /* maximum SPI I/O (can change) */
- Bufsize = 64,
-};
-
-/*
- * SPI software structures
- */
-
-struct Ctlr {
- Lock;
- QLock io;
- int init;
- SPI* spi;
- IOCparam* sp;
-
- BD* rd;
- BD* td;
- int phase;
- Rendez r;
- char* txbuf;
- char* rxbuf;
-};
-
-static Ctlr spictlr[1];
-
-/* dcflush isn't needed if rxbuf and txbuf allocated in uncached IMMR memory */
-#define DCFLUSH(a,n)
-
-static void interrupt(Ureg*, void*);
-
-/*
- * called by the reset routine of any driver using the SPI
- */
-void
-spireset(void)
-{
- IMM *io;
- SPI *spi;
- IOCparam *sp;
- CPMdev *cpm;
- Ctlr *ctlr;
-
- ctlr = spictlr;
- if(ctlr->init)
- return;
- ctlr->init = 1;
- cpm = cpmdev(CPspi);
- spi = cpm->regs;
- ctlr->spi = spi;
- sp = cpm->param;
- if(sp == nil){
- print("SPI: can't allocate new parameter memory\n");
- return;
- }
- ctlr->sp = sp;
-
- if(ctlr->rxbuf == nil)
- ctlr->rxbuf = cpmalloc(Bufsize, 2);
- if(ctlr->txbuf == nil)
- ctlr->txbuf = cpmalloc(Bufsize, 2);
-
- if(ctlr->rd == nil){
- ctlr->rd = bdalloc(1);
- ctlr->rd->addr = PADDR(ctlr->rxbuf);
- ctlr->rd->length = 0;
- ctlr->rd->status = BDWrap;
- }
- if(ctlr->td == nil){
- ctlr->td = bdalloc(1);
- ctlr->td->addr = PADDR(ctlr->txbuf);
- ctlr->td->length = 0;
- ctlr->td->status = BDWrap|BDLast;
- }
-
- /* select port pins */
- io = ioplock();
- io->pbdir |= SPICLK | SPIMOSI | SPIMISO;
- io->pbpar |= SPICLK | SPIMOSI | SPIMISO;
- iopunlock();
-
- /* explicitly initialise parameters, because InitRxTx can't be used (see i2c/spi relocation errata) */
- sp = ctlr->sp;
- sp->rbase = PADDR(ctlr->rd);
- sp->tbase = PADDR(ctlr->td);
- sp->rfcr = 0x18;
- sp->tfcr = 0x18;
- sp->mrblr = Bufsize;
- sp->rstate = 0;
- sp->rptr = 0;
- sp->rbptr = sp->rbase;
- sp->rcnt = 0;
- sp->tstate = 0;
- sp->tbptr = sp->tbase;
- sp->tptr = 0;
- sp->tcnt = 0;
- eieio();
-
- spi->spmode = MDiv16 | MRev | MMaster | ((8-1)<<4) | 1; /* 8 bit characters */
- if(0)
- spi->spmode |= MLoop; /* internal loop back mode for testing */
-
- spi->spie = ~0; /* clear events */
- eieio();
- spi->spim = MME|TXE|BSY|TXB|RXB;
- eieio();
- spi->spmode |= MEnable;
-
- intrenable(VectorCPIC+cpm->irq, interrupt, spictlr, BUSUNKNOWN, "spi");
-
-}
-
-enum {
- Idling,
- Waitval,
- Readyval
-};
-
-static void
-interrupt(Ureg*, void *arg)
-{
- int events;
- Ctlr *ctlr;
- SPI *spi;
-
- ctlr = arg;
- spi = ctlr->spi;
- events = spi->spie;
- eieio();
- spi->spie = events;
- if(events & (MME|BSY|TXE)){
- print("SPI#%x\n", events);
- if(ctlr->phase != Idling){
- ctlr->phase = Idling;
- wakeup(&ctlr->r);
- }
- }else if(events & RXB){
- if(ctlr->phase == Waitval){
- ctlr->phase = Readyval;
- wakeup(&ctlr->r);
- }
- }
-}
-
-static int
-done(void *a)
-{
- return ((Ctlr*)a)->phase != Waitval;
-}
-
-/*
- * send `nout' bytes on SPI from `out' and read as many bytes of reply into buffer `in';
- * return the number of bytes received, or -1 on error.
- */
-long
-spioutin(void *out, long nout, void *in)
-{
- Ctlr *ctlr;
- int nb, p;
-
- ctlr = spictlr;
- if(nout > Bufsize)
- return -1;
- qlock(&ctlr->io);
- if(waserror()){
- qunlock(&ctlr->io);
- return -1;
- }
- if(ctlr->phase != Idling)
- sleep(&ctlr->r, done, ctlr);
- memmove(ctlr->txbuf, out, nout);
- DCFLUSH(ctlr->txbuf, Bufsize);
- DCFLUSH(ctlr->rxbuf, Bufsize);
- ilock(ctlr);
- ctlr->phase = Waitval;
- ctlr->td->length = nout;
- ctlr->rd->status = BDEmpty|BDWrap|BDInt;
- ctlr->td->status = BDReady|BDWrap|BDLast;
- eieio();
- ctlr->spi->spcom = STR;
- eieio();
- iunlock(ctlr);
- sleep(&ctlr->r, done, ctlr);
- nb = ctlr->rd->length;
- if(nb > nout)
- nb = nout; /* shouldn't happen */
- p = ctlr->phase;
- poperror();
- qunlock(&ctlr->io);
- if(p != Readyval)
- return -1;
- memmove(in, ctlr->rxbuf, nb);
- return nb;
-}