SPI bus driver simplified.
This commit is contained in:
@@ -12,54 +12,55 @@
|
||||
|
||||
struct spi_dev spi_devices[MAXSPIDEV];
|
||||
|
||||
//
|
||||
// Default SPI bus speed
|
||||
|
||||
//
|
||||
#ifndef SPI_MHZ
|
||||
#define SPI_MHZ 10
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Open an SPI device in default mode. Use further function calls to
|
||||
// set baud rate, clock phase, etc.
|
||||
// Returns an integer for the number of the device (ala fd).
|
||||
// Returns -1 if no devices are available.
|
||||
|
||||
//
|
||||
int spi_open(unsigned int bus, unsigned int *tris, unsigned int pin)
|
||||
{
|
||||
int dno;
|
||||
struct spi_dev *dev;
|
||||
|
||||
// Find a free device
|
||||
for(dno=0; dno<MAXSPIDEV && spi_devices[dno].bus != NULL; dno++);
|
||||
for (dno=0; dno<MAXSPIDEV && spi_devices[dno].bus != NULL; dno++);
|
||||
|
||||
// or return if not found
|
||||
if(dno == MAXSPIDEV)
|
||||
if (dno == MAXSPIDEV)
|
||||
return -1;
|
||||
dev = &spi_devices[dno];
|
||||
|
||||
// Set up the device
|
||||
switch(bus)
|
||||
{
|
||||
case 1:
|
||||
spi_devices[dno].bus = (struct spireg *)&SPI1CON;
|
||||
break;
|
||||
case 2:
|
||||
spi_devices[dno].bus = (struct spireg *)&SPI2CON;
|
||||
break;
|
||||
case 3:
|
||||
spi_devices[dno].bus = (struct spireg *)&SPI3CON;
|
||||
break;
|
||||
case 4:
|
||||
spi_devices[dno].bus = (struct spireg *)&SPI4CON;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
switch (bus) {
|
||||
case 1:
|
||||
dev->bus = (struct spireg *)&SPI1CON;
|
||||
break;
|
||||
case 2:
|
||||
dev->bus = (struct spireg *)&SPI2CON;
|
||||
break;
|
||||
case 3:
|
||||
dev->bus = (struct spireg *)&SPI3CON;
|
||||
break;
|
||||
case 4:
|
||||
dev->bus = (struct spireg *)&SPI4CON;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
spi_devices[dno].cs_tris = tris;
|
||||
spi_devices[dno].cs_pin = pin;
|
||||
spi_devices[dno].baud = (BUS_KHZ / SPI_MHZ / 1000 + 1) / 2 - 1;
|
||||
spi_devices[dno].mode = PIC32_SPICON_MSTEN | PIC32_SPICON_ON;
|
||||
dev->cs_tris = tris;
|
||||
dev->cs_pin = pin;
|
||||
dev->baud = (BUS_KHZ / SPI_MHZ / 1000 + 1) / 2 - 1;
|
||||
dev->mode = PIC32_SPICON_MSTEN | PIC32_SPICON_ON;
|
||||
|
||||
if(tris)
|
||||
{
|
||||
if (tris) {
|
||||
// Configure the CS pin
|
||||
LAT_SET(*tris) = 1<<pin;
|
||||
TRIS_CLR(*tris) = 1<<pin;
|
||||
@@ -70,398 +71,464 @@ int spi_open(unsigned int bus, unsigned int *tris, unsigned int pin)
|
||||
|
||||
void spi_set_cspin(int dno, unsigned int *tris, unsigned int pin)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
// Revert the old CS pin to an input (release it)
|
||||
if(spi_devices[dno].cs_tris)
|
||||
{
|
||||
if (dev->cs_tris) {
|
||||
// Configure the CS pin
|
||||
TRIS_SET(*spi_devices[dno].cs_tris) = 1<<pin;
|
||||
TRIS_SET(*dev->cs_tris) = 1<<pin;
|
||||
}
|
||||
|
||||
spi_devices[dno].cs_tris = tris;
|
||||
spi_devices[dno].cs_pin = pin;
|
||||
if(tris)
|
||||
{
|
||||
dev->cs_tris = tris;
|
||||
dev->cs_pin = pin;
|
||||
if (tris) {
|
||||
// Configure the CS pin
|
||||
LAT_SET(*tris) = 1<<pin;
|
||||
TRIS_CLR(*tris) = 1<<pin;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close an SPI device
|
||||
// Free up the device entry, and turn off the CS pin (set it to input)
|
||||
|
||||
//
|
||||
void spi_close(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
if (spi_devices[dno].cs_tris != NULL) {
|
||||
if (dev->cs_tris != NULL) {
|
||||
// Revert the CS pin to input.
|
||||
TRIS_CLR(*spi_devices[dno].cs_tris) = 1<<spi_devices[dno].cs_pin;
|
||||
TRIS_CLR(*dev->cs_tris) = 1 << dev->cs_pin;
|
||||
}
|
||||
spi_devices[dno].cs_tris = NULL;
|
||||
dev->cs_tris = NULL;
|
||||
|
||||
// Disable the device (remove the bus pointer)
|
||||
spi_devices[dno].bus = NULL;
|
||||
dev->bus = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Assert the CS pin of a device.
|
||||
// Not only do we set the CS pin, but before we do so we also reconfigure
|
||||
// the SPI bus to the required settings for this device.
|
||||
//
|
||||
void spi_select(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
if (spi_devices[dno].cs_tris == NULL)
|
||||
if (dev->cs_tris == NULL)
|
||||
return;
|
||||
|
||||
spi_devices[dno].bus->brg = spi_devices[dno].baud;
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
dev->bus->brg = dev->baud;
|
||||
dev->bus->con = dev->mode;
|
||||
|
||||
LAT_CLR(*spi_devices[dno].cs_tris) = 1<<spi_devices[dno].cs_pin;
|
||||
LAT_CLR(*dev->cs_tris) = 1 << dev->cs_pin;
|
||||
}
|
||||
|
||||
//
|
||||
// Deassert the CS pin of a device.
|
||||
//
|
||||
void spi_deselect(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
if (spi_devices[dno].cs_tris == NULL)
|
||||
if (dev->cs_tris == NULL)
|
||||
return;
|
||||
|
||||
LAT_SET(*spi_devices[dno].cs_tris) = 1<<spi_devices[dno].cs_pin;
|
||||
LAT_SET(*dev->cs_tris) = 1 << dev->cs_pin;
|
||||
}
|
||||
|
||||
//
|
||||
// Set a mode setting or two - just updates the internal records, the
|
||||
// actual mode is changed next time the CS is asserted
|
||||
//
|
||||
void spi_set(int dno, unsigned int set)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
spi_devices[dno].mode |= set;
|
||||
dev->mode |= set;
|
||||
}
|
||||
|
||||
//
|
||||
// Clear a mode setting or two - just updates the internal records, the
|
||||
// actual mode is changed next time the CS is asserted
|
||||
//
|
||||
void spi_clr(int dno, unsigned int set)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
spi_devices[dno].mode &= ~set;
|
||||
dev->mode &= ~set;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the current status of the SPI bus for the device in question
|
||||
// Just returns the ->stat entry in the register set.
|
||||
//
|
||||
unsigned int spi_status(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return 0;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return 0;
|
||||
|
||||
return spi_devices[dno].bus->stat;
|
||||
return dev->bus->stat;
|
||||
}
|
||||
|
||||
//
|
||||
// Transfer one word of data, and return the read word of
|
||||
// data. The actual number of bits sent depends on the
|
||||
// mode of the transfer.
|
||||
// This is blocking, and waits for the transfer to complete
|
||||
// before returning. Times out after a certain period.
|
||||
//
|
||||
unsigned char spi_transfer(int dno, unsigned char data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
unsigned int to = 100000;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return 0xF0;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return 0xF1;
|
||||
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
spi_devices[dno].bus->brg = spi_devices[dno].baud;
|
||||
reg->con = dev->mode;
|
||||
reg->brg = dev->baud;
|
||||
|
||||
spi_devices[dno].bus->buf = data;
|
||||
while ((--to > 0) && (!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBF)))
|
||||
reg->buf = data;
|
||||
while ((--to > 0) && ! (reg->stat & PIC32_SPISTAT_SPIRBF))
|
||||
asm volatile ("nop");
|
||||
|
||||
if(to == 0)
|
||||
if (to == 0)
|
||||
return 0xF2;
|
||||
|
||||
return spi_devices[dno].bus->buf;
|
||||
return reg->buf;
|
||||
}
|
||||
|
||||
//
|
||||
// Write a huge chunk of data as fast and as efficiently as
|
||||
// possible. Switches in to 32-bit mode regardless, and uses
|
||||
// the enhanced buffer mode.
|
||||
// Data should be a multiple of 32 bits.
|
||||
//
|
||||
void spi_bulk_write_32_be(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *data32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = mips_bswap(*data32++);
|
||||
reg->buf = mips_bswap(*data32++);
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
(void) spi_devices[dno].bus->buf;
|
||||
(void) reg->buf;
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_write_32(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *data32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = *data32++;
|
||||
reg->buf = *data32++;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
(void) spi_devices[dno].bus->buf;
|
||||
(void) reg->buf;
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_write_16(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
short *data16 = (short *)data;
|
||||
unsigned int words = len >> 1;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = *data16++;
|
||||
reg->buf = *data16++;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
(void) spi_devices[dno].bus->buf;
|
||||
(void) reg->buf;
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_write(int dno, unsigned int len, unsigned char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
unsigned char *data8 = data;
|
||||
unsigned int i;
|
||||
unsigned char out;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
for (i=0; i<len; i++) {
|
||||
out = *data8;
|
||||
spi_transfer(dno, out);
|
||||
data8++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read a huge chunk of data as fast and as efficiently as
|
||||
// possible. Switches in to 32-bit mode regardless, and uses
|
||||
// the enhanced buffer mode.
|
||||
// Data should be a multiple of 32 bits.
|
||||
//
|
||||
void spi_bulk_read_32_be(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *data32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = ~0;
|
||||
reg->buf = ~0;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*data32++ = mips_bswap(spi_devices[dno].bus->buf);
|
||||
*data32++ = mips_bswap(reg->buf);
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_read_32(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *data32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = ~0;
|
||||
reg->buf = ~0;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*data32++ = spi_devices[dno].bus->buf;
|
||||
*data32++ = reg->buf;
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_read_16(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
short *data16 = (short *)data;
|
||||
unsigned int words = len >> 1;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = ~0;
|
||||
reg->buf = ~0;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*data16++ = mips_bswap(spi_devices[dno].bus->buf);
|
||||
*data16++ = mips_bswap(reg->buf);
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_read(int dno, unsigned int len, unsigned char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
unsigned char *data8 = data;
|
||||
unsigned int i;
|
||||
unsigned char in,out;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
for (i=0; i<len; i++) {
|
||||
out = 0xFF;
|
||||
in = spi_transfer(dno, out);
|
||||
*data8 = in;
|
||||
@@ -471,123 +538,136 @@ void spi_bulk_read(int dno, unsigned int len, unsigned char *data)
|
||||
|
||||
void spi_bulk_rw_32_be(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *read32 = (int *)data;
|
||||
int *write32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = *write32++;
|
||||
reg->buf = *write32++;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*read32++ = mips_bswap(spi_devices[dno].bus->buf);
|
||||
*read32++ = mips_bswap(reg->buf);
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_rw_32(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
int *read32 = (int *)data;
|
||||
int *write32 = (int *)data;
|
||||
unsigned int words = len >> 2;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE32 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = *write32++;
|
||||
reg->buf = *write32++;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*read32++ = spi_devices[dno].bus->buf;
|
||||
*read32++ = reg->buf;
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_rw_16(int dno, unsigned int len, char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
struct spireg *reg;
|
||||
short *read16 = (short *)data;
|
||||
short *write16 = (short *)data;
|
||||
unsigned int words = len >> 1;
|
||||
unsigned int nread;
|
||||
unsigned int nwritten;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
reg = dev->bus;
|
||||
if (! reg)
|
||||
return;
|
||||
|
||||
nread = 0;
|
||||
nwritten = words;
|
||||
|
||||
spi_devices[dno].bus->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while(nread < words)
|
||||
reg->conset = PIC32_SPICON_MODE16 | PIC32_SPICON_ENHBUF;
|
||||
while (nread < words)
|
||||
{
|
||||
if(nwritten > 0 && !(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPITBF))
|
||||
if (nwritten > 0 && ! (reg->stat & PIC32_SPISTAT_SPITBF))
|
||||
{
|
||||
spi_devices[dno].bus->buf = *write16++;
|
||||
reg->buf = *write16++;
|
||||
nwritten--;
|
||||
}
|
||||
|
||||
if(!(spi_devices[dno].bus->stat & PIC32_SPISTAT_SPIRBE))
|
||||
if (! (reg->stat & PIC32_SPISTAT_SPIRBE))
|
||||
{
|
||||
*read16++ = mips_bswap(spi_devices[dno].bus->buf);
|
||||
*read16++ = mips_bswap(reg->buf);
|
||||
nread++;
|
||||
}
|
||||
}
|
||||
spi_devices[dno].bus->con = spi_devices[dno].mode;
|
||||
reg->con = dev->mode;
|
||||
}
|
||||
|
||||
void spi_bulk_rw(int dno, unsigned int len, unsigned char *data)
|
||||
{
|
||||
struct spi_dev *dev;
|
||||
unsigned char *data8 = data;
|
||||
unsigned int i;
|
||||
unsigned char in,out;
|
||||
|
||||
if(dno >= MAXSPIDEV)
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
for (i=0; i<len; i++) {
|
||||
out = *data8;
|
||||
in = spi_transfer(dno, out);
|
||||
*data8 = in;
|
||||
@@ -595,84 +675,102 @@ void spi_bulk_rw(int dno, unsigned int len, unsigned char *data)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set the SPI baud rate for a device (in KHz)
|
||||
|
||||
//
|
||||
void spi_brg(int dno, unsigned int baud)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return;
|
||||
|
||||
spi_devices[dno].baud = (BUS_KHZ / baud + 1) / 2 - 1;
|
||||
dev->baud = (BUS_KHZ / baud + 1) / 2 - 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the name of the SPI bus for a device
|
||||
|
||||
//
|
||||
char *spi_name(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return "SPI?";
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return "NO SPI BUS";
|
||||
|
||||
if(spi_devices[dno].bus == (struct spireg *)&SPI1CON)
|
||||
if (dev->bus == (struct spireg *)&SPI1CON)
|
||||
return "SPI1";
|
||||
|
||||
if(spi_devices[dno].bus == (struct spireg *)&SPI2CON)
|
||||
if (dev->bus == (struct spireg *)&SPI2CON)
|
||||
return "SPI2";
|
||||
|
||||
if(spi_devices[dno].bus == (struct spireg *)&SPI3CON)
|
||||
if (dev->bus == (struct spireg *)&SPI3CON)
|
||||
return "SPI3";
|
||||
|
||||
if(spi_devices[dno].bus == (struct spireg *)&SPI4CON)
|
||||
if (dev->bus == (struct spireg *)&SPI4CON)
|
||||
return "SPI4";
|
||||
|
||||
return "SPI?";
|
||||
}
|
||||
|
||||
//
|
||||
// Return the port name of the CS pin for a device
|
||||
//
|
||||
char spi_csname(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return '?';
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return '?';
|
||||
|
||||
switch((unsigned int)spi_devices[dno].cs_tris)
|
||||
{
|
||||
case (unsigned int)&TRISA: return 'A';
|
||||
case (unsigned int)&TRISB: return 'B';
|
||||
case (unsigned int)&TRISC: return 'C';
|
||||
case (unsigned int)&TRISD: return 'D';
|
||||
case (unsigned int)&TRISE: return 'E';
|
||||
case (unsigned int)&TRISF: return 'F';
|
||||
case (unsigned int)&TRISG: return 'G';
|
||||
switch ((unsigned)dev->cs_tris) {
|
||||
case (unsigned)&TRISA: return 'A';
|
||||
case (unsigned)&TRISB: return 'B';
|
||||
case (unsigned)&TRISC: return 'C';
|
||||
case (unsigned)&TRISD: return 'D';
|
||||
case (unsigned)&TRISE: return 'E';
|
||||
case (unsigned)&TRISF: return 'F';
|
||||
case (unsigned)&TRISG: return 'G';
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
|
||||
int spi_cspin(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return '?';
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return '?';
|
||||
|
||||
return spi_devices[dno].cs_pin;
|
||||
return dev->cs_pin;
|
||||
}
|
||||
|
||||
unsigned int spi_get_brg(int dno)
|
||||
{
|
||||
if(dno >= MAXSPIDEV)
|
||||
struct spi_dev *dev;
|
||||
|
||||
if (dno >= MAXSPIDEV)
|
||||
return 0;
|
||||
|
||||
if(spi_devices[dno].bus==NULL)
|
||||
dev = &spi_devices[dno];
|
||||
if (! dev->bus)
|
||||
return 0;
|
||||
|
||||
return BUS_KHZ / (spi_devices[dno].baud + 1) / 2;
|
||||
return BUS_KHZ / (dev->baud + 1) / 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user