diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/spi.c | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/spi.c')
| -rw-r--r-- | os/mpc/spi.c | 243 |
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; -} |
