static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords) { FAR uint8_t *ptr = (FAR uint8_t*)buffer; uint32_t rxpending = 0; /* While there is remaining to be sent (and no synchronization error has occurred) */ spidbg("nwords: %d\n", nwords); while (nwords || rxpending) { /* Fill the transmit FIFO with 0xff... * Write 0xff to the data register while (1) the TX FIFO is * not full, (2) we have not exceeded the depth of the TX FIFO, * and (3) there are more bytes to be sent. */ spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords); while ((getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF) && (rxpending < LPC214X_SPI1_FIFOSZ) && nwords) { putreg16(0xff, LPC214X_SPI1_DR); nwords--; rxpending++; } /* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */ spivdbg("RX: rxpending: %d\n", rxpending); while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE) { *ptr++ = (uint8_t)getreg16(LPC214X_SPI1_DR); rxpending--; } } }
int pga11x_uselect(PGA11X_HANDLE handle, int pos, FAR const struct pga11x_usettings_s *settings) { FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; uint16_t u1cmd; uint16_t u2cmd; spivdbg("channel: %d gain: %d\n", settings->channel, settings->gain); DEBUGASSERT(handle); /* Format the commands */ if (pos == 0) { u1cmd = PGA11X_CMD_WRITE | ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) | ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT); u2cmd = PGA11X_DCCMD_NOOP; } else /* if (pos == 1) */ { u1cmd = PGA11X_CMD_NOOP; u2cmd = PGA11X_DCCMD_WRITE | ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) | ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT); } /* Send the command */ pga11x_write(spi, u1cmd, u2cmd); return OK; }
int pga11x_select(PGA11X_HANDLE handle, FAR const struct pga11x_settings_s *settings) { #ifndef CONFIG_PGA11X_DAISYCHAIN FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; uint16_t cmd; DEBUGASSERT(handle && settings); spivdbg("channel: %d gain: %d\n", settings->channel, settings->gain); /* Format the command */ cmd = PGA11X_CMD_WRITE | ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) | ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT); /* Send the command */ pga11x_write(spi, cmd); return OK; #else FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; uint16_t u1cmd; uint16_t u2cmd; DEBUGASSERT(handle && settings); spivdbg("U1 channel: %d gain: %d\n", settings->u1.channel, settings->u1.gain); spivdbg("U1 channel: %d gain: %d\n", settings->u1.channel, settings->u1.gain); /* Format the commands */ u1cmd = PGA11X_CMD_WRITE | ((uint16_t)settings->u1.channel << PGA11X_CHAN_SHIFT) | ((uint16_t)settings->u1.gain << PGA11X_GAIN_SHIFT); u2cmd = PGA11X_DCCMD_WRITE | ((uint16_t)settings->u2.channel << PGA11X_CHAN_SHIFT) | ((uint16_t)settings->u2.gain << PGA11X_GAIN_SHIFT); /* Send the command */ pga11x_write(spi, u1cmd, u2cmd); return OK; #endif }
PGA11X_HANDLE pga11x_initialize(FAR struct spi_dev_s *spi) { spivdbg("Entry\n"); /* No Special state is required, just return the SPI driver instance as * the handle. This gives us a place to extend functionality in the * future if neccessary. */ return (PGA11X_HANDLE)spi; }
static void pga11x_write(FAR struct spi_dev_s *spi, uint16_t cmd) { spivdbg("cmd %04x\n", cmd); /* Lock, select, send the 16-bit command, de-select, and un-lock. */ pga11x_lock(spi); SPI_SELECT(spi, SPIDEV_MUX, true); pga11x_send16(spi, cmd); SPI_SELECT(spi, SPIDEV_MUX, false); pga11x_unlock(spi); }
static void pga11x_send16(FAR struct spi_dev_s *spi, uint16_t word) { spivdbg("Send %04x\n", word); /* The logical interface is 16-bits wide. However, this driver uses a * 8-bit configuration for greaer portability. * * Send the MS byte first. Then the LS byte. */ SPI_SEND(spi, word >> 8); SPI_SEND(spi, word & 0xff); }
static void pga11x_configure(FAR struct spi_dev_s *spi) { spivdbg("MODE: %d BITS: 8 Frequency: %d\n", CONFIG_PGA11X_SPIMODE, CONFIG_PGA11X_SPIFREQUENCY); /* Call the setfrequency, setbits, and setmode methods to make sure that * the SPI is properly configured for the device. */ SPI_SETMODE(spi, CONFIG_PGA11X_SPIMODE); SPI_SETBITS(spi, 8); (void)SPI_HWFEATURES(spi, 0); (void)SPI_SETFREQUENCY(spi, CONFIG_PGA11X_SPIFREQUENCY); }
void stm32_spiinitialize(void) { /* NOTE: Clocking for SPI1 and/or SPI2 was already provided in stm32_rcc.c. * Configurations of SPI pins is performed in stm32_spi.c. * Here, we only initialize chip select pins unique to the board * architecture. */ #ifdef CONFIG_STM32_SPI1 /* Configure the SPI-based touch screen CS GPIO */ spivdbg("Configure GPIO for SPI1/CS\n"); stm32_configgpio(GPIO_TS_CS); #endif }
static void pga11x_write(FAR struct spi_dev_s *spi, uint16_t u1cmd, uint16_t u2cmd) { spivdbg("U1 cmd: %04x U2 cmd: %04x\n", u1cmd, u2cmd); /* Lock, select, send the U2 16-bit command, the U1 16-bit command, de-select, * and un-lock. */ pga11x_lock(spi); SPI_SELECT(spi, SPIDEV_MUX, true); pga11x_send16(spi, u2cmd); pga11x_send16(spi, u1cmd); SPI_SELECT(spi, SPIDEV_MUX, false); pga11x_unlock(spi); }
int pga11x_shutdown(PGA11X_HANDLE handle) { FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; spivdbg("Entry\n"); DEBUGASSERT(handle); /* Enter shutdown mode by issuing an SDN_EN command */ #ifdef CONFIG_PGA11X_DAISYCHAIN pga11x_write(spi, PGA11X_CMD_SDN_EN, PGA11X_DCCMD_SDN_EN); #else pga11x_write(spi, PGA11X_CMD_SDN_EN); #endif return OK; }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { switch(devid) { #ifdef CONFIG_WL_NRF24L01 case SPIDEV_WIRELESS: spivdbg("nRF24L01 device %s\n", selected ? "asserted" : "de-asserted"); /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_NRF24L01_CS, !selected); break; #endif default: break; } }
static uint16_t pga11x_recv16(FAR struct spi_dev_s *spi) { uint8_t msb; uint8_t lsb; /* The logical interface is 16-bits wide. However, this driver uses a * 8-bit configuration for greaer portability. * * Send a dummy byte and receive MS byte first. Then the LS byte. */ msb = SPI_SEND(spi, SPI_DUMMY); lsb = SPI_SEND(spi, SPI_DUMMY); spivdbg("Received %02x %02x\n", msb, lsb); return ((uint16_t)msb << 8) | (uint16_t)lsb; }
uint8_t pic32mx_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { uint8_t ret = 0; /* Card detect is pull up on-board. If a low value is sensed then the * card must be present. */ #ifdef PIC32_HAVE_SD if (devid == SPIDEV_MMCSD) { if (!pic32mx_gpioread(GPIO_SD_CD)) { ret = SPI_STATUS_PRESENT; /* It seems that a high value indicates the card is write * protected. */ if (pic32mx_gpioread(GPIO_SD_WD)) { ret |= SPI_STATUS_WRPROTECTED; } } } #endif #ifdef PIC32_HAVE_SOIC if (devid == SPIDEV_FLASH) { ret = SPI_STATUS_PRESENT; /* Write protect is indicated with a low value. */ if (pic32mx_gpioread(GPIO_SOIC_WP)) { ret |= SPI_STATUS_WRPROTECTED; } } #endif spivdbg("Returning %d\n", ret); return ret; }
int pga11x_enable(PGA11X_HANDLE handle) { FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; spivdbg("Entry\n"); DEBUGASSERT(handle); /* Lock the bus and send the shutdown disable command. Shutdown mode is * cleared (returned to the last valid write configuration) by the SDN_DIS * command or by any valid Write command */ #ifdef CONFIG_PGA11X_DAISYCHAIN pga11x_write(spi, PGA11X_CMD_SDN_DIS, PGA11X_DCCMD_SDN_DIS); #else pga11x_write(spi, PGA11X_CMD_SDN_DIS); #endif return OK; }
void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spivdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); /* The SD card chip select is pulled high and active low */ #ifdef PIC32_HAVE_SD if (devid == SPIDEV_MMCSD) { pic32mx_gpiowrite(GPIO_SD_CS, !selected); } #endif #ifdef PIC32_HAVE_SOIC if (devid == SPIDEV_FLASH) { pic32mx_gpiowrite(GPIO_SOIC_CS, !selected); } #endif }
int pga11x_uenable(PGA11X_HANDLE handle, int pos) { FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; spivdbg("Entry\n"); DEBUGASSERT(handle); /* Enter shutdown mode by issuing an SDN_EN command */ if (pos == 0) { pga11x_write(spi, PGA11X_CMD_SDN_DIS, PGA11X_DCCMD_NOOP); } else { pga11x_write(spi, PGA11X_CMD_NOOP, PGA11X_DCCMD_SDN_DIS); } return OK; }
static void pga11x_lock(FAR struct spi_dev_s *spi) { spivdbg("Locking\n"); /* On SPI busses where there are multiple devices, it will be necessary to * lock SPI to have exclusive access to the busses for a sequence of * transfers. The bus should be locked before the chip is selected. * * This is a blocking call and will not return until we have exclusiv access to * the SPI buss. We will retain that exclusive access until the bus is unlocked. */ SPI_LOCK(spi, true); /* After locking the SPI bus, the we also need call the setfrequency, setbits, and * setmode methods to make sure that the SPI is properly configured for the device. * If the SPI buss is being shared, then it may have been left in an incompatible * state. */ pga11x_configure(spi); }
void kl_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spivdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); }
int pga11x_read(PGA11X_HANDLE handle, FAR struct pga11x_settings_s *settings) { #ifdef CONFIG_PGA11X_DAISYCHAIN FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; uint16_t u1value; uint16_t u2value; spivdbg("Entry\n"); DEBUGASSERT(handle && settings); /* Lock the bus and read the configuration */ pga11x_lock(spi); /* Select, send the 16-bit command, the 16-bit daisy-chain command, and * then de-select the part. I do not know if de-selection between word * transfers is required. However, it is shown in the timing diagrams * for the part. */ SPI_SELECT(spi, SPIDEV_MUX, true); pga11x_send16(spi, PGA11X_CMD_READ); pga11x_send16(spi, PGA11X_DCCMD_READ); SPI_SELECT(spi, SPIDEV_MUX, false); /* Re-select, get the returned values, de-select, and unlock */ SPI_SELECT(spi, SPIDEV_MUX, true); u2value = pga11x_recv16(spi); u1value = pga11x_recv16(spi); SPI_SELECT(spi, SPIDEV_MUX, false); pga11x_unlock(spi); /* Decode the returned value */ spivdbg("Returning %04x %04x\n", u2value, u1value); settings->u1.channel = (uint8_t)((u1value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT); settings->u1.gain = (uint8_t)((u1value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT); settings->u2.channel = (uint8_t)((u2value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT); settings->u2.gain = (uint8_t)((u2value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT); return OK; #else FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle; uint16_t value; spivdbg("Entry\n"); DEBUGASSERT(handle); /* Lock the bus and read the configuration */ pga11x_lock(spi); /* Select, send the 16-bit PGA11X_CMD_READ command, and de-select. I do * not know if de-selection between word transfers is required. However, * it is shown in the timing diagrams for the part. */ SPI_SELECT(spi, SPIDEV_MUX, true); pga11x_send16(spi, PGA11X_CMD_READ); SPI_SELECT(spi, SPIDEV_MUX, false); /* Re-select, get the returned value, de-select, and unlock */ SPI_SELECT(spi, SPIDEV_MUX, true); value = pga11x_recv16(spi); SPI_SELECT(spi, SPIDEV_MUX, false); pga11x_unlock(spi); /* Decode the returned value */ spivdbg("Returning: %04x\n", value); settings->channel = (uint8_t)((value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT); settings->gain = (uint8_t)((value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT); return OK; #endif }
static inline void pga11x_unlock(FAR struct spi_dev_s *spi) { spivdbg("Unlocking\n"); SPI_LOCK(spi, false); }