static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords) { FAR const uint8_t *ptr = (FAR const uint8_t *)buffer; uint8_t sr; /* Loop while thre are bytes remaining to be sent */ spidbg("nwords: %d\n", nwords); while (nwords > 0) { /* While the TX FIFO is not full and there are bytes left to send */ while ((getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF) && nwords) { /* Send the data */ putreg16((uint16_t)*ptr, LPC214X_SPI1_DR); ptr++; nwords--; } } /* Then discard all card responses until the RX & TX FIFOs are emptied. */ spidbg("discarding\n"); do { /* Is there anything in the RX fifo? */ sr = getreg8(LPC214X_SPI1_SR); if ((sr & LPC214X_SPI1SR_RNE) != 0) { /* Yes.. Read and discard */ (void)getreg16(LPC214X_SPI1_DR); } /* There is a race condition where TFE may go true just before * RNE goes true and this loop terminates prematurely. The nasty little * delay in the following solves that (it could probably be tuned * to improve performance). */ else if ((sr & LPC214X_SPI1SR_TFE) != 0) { up_udelay(100); sr = getreg8(LPC214X_SPI1_SR); } } while ((sr & LPC214X_SPI1SR_RNE) != 0 || (sr & LPC214X_SPI1SR_TFE) == 0); }
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { #ifdef CONFIG_DEBUG_SPI uint32_t regval; #endif uint32_t bit = 1 << 20; /* We do not bother to check if devid == SPIDEV_DISPLAY because that is the * only thing on the bus. */ #ifdef CONFIG_DEBUG_SPI regval = getreg32(CS_PIN_REGISTER); #endif if (selected) { /* Enable slave select (low enables) */ putreg32(bit, CS_CLR_REGISTER); spidbg("CS asserted: %08x->%08x\n", regval, getreg32(CS_PIN_REGISTER)); } else { /* Disable slave select (low enables) */ putreg32(bit, CS_SET_REGISTER); spidbg("CS de-asserted: %08x->%08x\n", regval, getreg32(CS_PIN_REGISTER)); /* Wait for the TX FIFO not full indication */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF)); putreg16(0xff, LPC214X_SPI1_DR); /* Wait until TX FIFO and TX shift buffer are empty */ while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_BSY); /* Wait until RX FIFO is not empty */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)); /* Then read and discard bytes until the RX FIFO is empty */ do { (void)getreg16(LPC214X_SPI1_DR); } while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE); } }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #if 0 /* Need to study this */ if (devid == SPIDEV_LCD) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_LCD_CS, !selected); } else #endif #ifdef CONFIG_ENC28J60 if (devid == SPIDEV_ETHERNET) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_ENC28J60_CS, !selected); } #else if (devid == SPIDEV_FLASH) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_FLASH_CS, !selected); } #endif }
void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); /* SPI3 connects to TFT LCD (for touchscreen and SD) and the RF24L01 2.4G * wireless module. */ if (devid == SPIDEV_TOUCHSCREEN) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_TP_CS, !selected); } else if (devid == SPIDEV_MMCSD) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_LCDDF_CS, !selected); } else if (devid == SPIDEV_FLASH) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_LCDSD_CS, !selected); } else if (devid == SPIDEV_WIRELESS) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_WIRELESS_CS, !selected); } }
void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); /* there can only be one device on this bus, so always select it */ stm32_gpiowrite(GPIO_SPI_CS_SDCARD, !selected); }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { const char *type; switch (devid) { #ifdef CONFIG_WL_CC3000 case SPIDEV_WIRELESS: type = "wireless"; break; #endif default: type = "unknown"; break; } spidbg("devid: %d, type: %s, CS: %sassert\n", (int)devid, type, selected ? "" : "de-"); (void)type; if (0) { } #ifdef CONFIG_WL_CC3000 else if (devid == SPIDEV_WIRELESS) { board_set_chip_select(CHIP_SELECT_SPI1_WLAN, selected); } #endif }
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 stm32_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) { const char *type; switch (devid) { case SPIDEV_DISPLAY: type = "display"; break; default: type = "unknown"; break; } spidbg("devid: %d, type: %s, cmddata: %sassert\n", (int)devid, type, cmd ? "" : "de-"); (void)type; if (devid == SPIDEV_DISPLAY) { bool default_on = !!(GPIO_LCD_SSD1309_CMDDATA & GPIO_OUTPUT_SET); stm32_gpiowrite(GPIO_LCD_SSD1309_CMDDATA, !!cmd ^ default_on); } return -ENODEV; }
void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { const char *type; switch (devid) { #ifdef CONFIG_MMCSD case SPIDEV_MMCSD: type = "mmcsd"; break; #endif default: type = "unknown"; break; } spidbg("devid: %d, type: %s, CS: %sassert\n", (int)devid, type, selected ? "" : "de-"); (void)type; if (0) { } #ifdef CONFIG_MMCSD else if (devid == SPIDEV_MMCSD) { board_set_chip_select(CHIP_SELECT_SPI3_SDCARD, selected); } #endif }
void weak_function stm32_spiinitialize(void) { #ifdef CONFIG_STM32_SPI1 /* Configure SPI-based devices */ g_spi1 = up_spiinitialize(1); if (!g_spi1) { spidbg("[boot] FAILED to initialize SPI port 1\n"); } #ifdef CONFIG_WL_CC3000 stm32_configgpio(GPIO_SPI_CS_WIFI); #endif #ifdef HAVE_MMCSD stm32_configgpio(GPIO_SPI_CS_SD_CARD); #endif #endif #ifdef CONFIG_STM32_SPI2 /* Configure SPI-based devices */ g_spi2 = up_spiinitialize(2); /* Setup CS, EN & IRQ line IOs */ #ifdef CONFIG_WL_CC3000 stm32_configgpio(GPIO_WIFI_CS); stm32_configgpio(GPIO_WIFI_EN); stm32_configgpio(GPIO_WIFI_INT); #endif #endif }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); if (devid == SPIDEV_USER) { stm32_gpiowrite(USER_CSn, !selected); } }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); switch (devid) { case PX4_SPIDEV_GYRO: stm32_gpiowrite(GPIO_SPI_CS_GYRO, !selected); break; case PX4_SPIDEV_ACCEL: stm32_gpiowrite(GPIO_SPI_CS_ACCEL, !selected); break; default: spidbg("devid: %d - unexpected\n", devid); break; } }
void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); if (devid == SPIDEV_FLASH) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_FRAM_CS, !selected); } }
void pic32mx_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); if (devid == SPIDEV_MMCSD) { pic32mx_gpiowrite(GPIO_SD_CS, !selected); } }
static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { /* I don't think there is anyway to determine these things on the mcu123.com * board. */ spidbg("Return SPI_STATUS_PRESENT\n"); return SPI_STATUS_PRESENT; }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #if defined(CONFIG_MMCSD) if (devid == SPIDEV_MMCSD) { stm32_gpiowrite(MMCSD_CSn, !selected); } #endif }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_WL_CC3000 if (devid == SPIDEV_WIRELESS) { stm32_gpiowrite(GPIO_WIFI_CS, !selected); } #endif }
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { uint32_t bit = 1 << 20; if (selected) { /* Enable slave select (low enables) */ spidbg("CD asserted\n"); putreg32(bit, CS_CLR_REGISTER); } else { /* Disable slave select (low enables) */ spidbg("CD de-asserted\n"); putreg32(bit, CS_SET_REGISTER); /* Wait for the TX FIFO not full indication */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF)); putreg16(0xff, LPC214X_SPI1_DR); /* Wait until TX FIFO and TX shift buffer are empty */ while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_BSY); /* Wait until RX FIFO is not empty */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)); /* Then read and discard bytes until the RX FIFO is empty */ do { (void)getreg16(LPC214X_SPI1_DR); } while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE); } }
void pic32mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); if (devid == SPIDEV_FLASH) { pic32mx_gpiowrite(GPIO_SST25VF032B_CS, !selected); } else if (devid == SPIDEV_MUX) { pic32mx_gpiowrite(GPIO_PGA117_CS, !selected); } }
static int spi_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) { #ifdef CONFIG_DEBUG_SPI uint32_t regval; #endif uint32_t bit = 1 << 23; /* We do not bother to check if devid == SPIDEV_DISPLAY because that is the * only thing on the bus. */ /* "This is the Data/Command control pad which determines whether the * data bits are data or a command. * * A0 = H: the inputs at D0 to D7 are treated as display data. * A0 = L: the inputs at D0 to D7 are transferred to the command registers." */ #ifdef CONFIG_DEBUG_SPI regval = getreg32(CS_PIN_REGISTER); #endif if (cmd) { /* L: the inputs at D0 to D7 are transferred to the command registers */ putreg32(bit, CS_CLR_REGISTER); spidbg("Command: %08x->%08x\n", regval, getreg32(CS_PIN_REGISTER)); } else { /* H: the inputs at D0 to D7 are treated as display data. */ putreg32(bit, CS_SET_REGISTER); spidbg("Data: %08x->%08x\n", regval, getreg32(CS_PIN_REGISTER)); } return OK; }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_INPUT_ADS7843E /* Select/de-select the touchscreen */ if (devid == SPIDEV_TOUCHSCREEN) { stm32_gpiowrite(GPIO_LCDTP_CS, !selected); } #endif }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_LCD_UG2864AMBAG01 if (devid == SPIDEV_DISPLAY) { stm32_gpiowrite(GPIO_OLED_CS, !selected); } else #endif { stm32_gpiowrite(GPIO_CS_MEMS, !selected); } }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); if (devid == SPIDEV_WIRELESS) { stm32_gpiowrite(GPIO_CC1101_CS, !selected); /* Wait for MISO to go low, indicates that Quart has stabilized */ if (selected) { while( stm32_gpioread(GPIO_SPI2_MISO) ) up_waste(); } } }
int sam3u_spiselect(enum spi_dev_e devid) { int cs = -EINVAL; #if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E) if (devid == SPIDEV_TOUCHSCREEN) { /* Assert the CS pin to the OLED display */ cs = 2; } #endif spidbg("devid: %d CS: %d\n", (int)devid, cs); return cs; }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_WL_CC3000 if (devid == SPIDEV_WIRELESS) { stm32_gpiowrite(GPIO_SPI_CS_WIFI, !selected); } else #endif #ifdef HAVE_MMCSD if (devid == SPIDEV_MMCSD) { stm32_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected); } #endif }
void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); /* SPI1 connects to the SD CARD and to the SPI FLASH */ if (devid == SPIDEV_MMCSD) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_SD_CS, !selected); } else if (devid == SPIDEV_FLASH) { /* Set the GPIO low to select and high to de-select */ stm32_gpiowrite(GPIO_FLASH_CS, !selected); } }
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) { uint32_t divisor = LPC214X_PCLKFREQ / frequency; if (divisor < 2) { divisor = 2; } else if (divisor > 254) { divisor = 254; } divisor = (divisor + 1) & ~1; putreg8(divisor, LPC214X_SPI1_CPSR); spidbg("Frequency %d->%d\n", frequency, LPC214X_PCLKFREQ / divisor); return LPC214X_PCLKFREQ / divisor; }
void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { const char *type; switch (devid) { case SPIDEV_DISPLAY: type = "display"; break; default: type = "unknown"; break; } spidbg("devid: %d, type: %s, CS: %sassert\n", (int)devid, type, selected ? "" : "de-"); (void)type; if (devid == SPIDEV_DISPLAY) { board_set_chip_select(CHIP_SELECT_SPI2_DISPLAY, selected); } }
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) { register uint16_t regval; /* Wait while the TX FIFO is full */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF)); /* Write the byte to the TX FIFO */ putreg16((uint8_t)wd, LPC214X_SPI1_DR); /* Wait for the RX FIFO not empty */ while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)); /* Get the value from the RX FIFO and return it */ regval = getreg16(LPC214X_SPI1_DR); spidbg("%04x->%04x\n", wd, regval); return regval; }
uint8_t pic32mx_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { uint8_t ret = 0; /* Card detect active low. */ if (devid == SPIDEV_MMCSD) { if (!pic32mx_gpioread(GPIO_SD_CD)) { ret = SPI_STATUS_PRESENT; /* A high value indicates the the card is write protected. */ if (pic32mx_gpioread(GPIO_SD_WP)) { ret |= SPI_STATUS_WRPROTECTED; } } } spidbg("Returning %02x\n", ret); return ret; }