/** * \brief Send command to dataflash. * \return True for OK. */ static bool spi_send_cmd(spi_cmd_t *p_cmd) { spi_status_t rc; int i; uint16_t data; uint8_t pcs, last = 0; /* Clear dummy byte */ if (spi_is_rx_full(CONF_TEST_SPI)) spi_read(CONF_TEST_SPI, &data, &pcs); /* Wait until no activity on bus */ while(!spi_is_tx_empty(CONF_TEST_SPI)); /* Send command */ for (i = 0; i < p_cmd->cmd_size; i ++) { last = (i == (p_cmd->cmd_size-1)) && (p_cmd->dummy_size == 0) && (p_cmd->data_size == 0); rc = spi_write(CONF_TEST_SPI, p_cmd->cmd[i], TEST_DF_PCS, last); if (p_cmd->cmd_rx) rc |= spi_read(CONF_TEST_SPI, &data, &pcs); if (rc != SPI_OK) return false; } /* Send dummy clocks */ for (i = 0; i < p_cmd->dummy_size; i ++) { rc = spi_write(CONF_TEST_SPI, 0xFF, TEST_DF_PCS, 0); if (p_cmd->cmd_rx) rc |= spi_read(CONF_TEST_SPI, &data, &pcs); if (rc != SPI_OK) return false; } if (p_cmd->data_size == 0) return true; /* Read/Write data */ for (i = 0; i < p_cmd->data_size; i ++) { last = (i == (p_cmd->data_size-1)); rc = spi_write(CONF_TEST_SPI, p_cmd->data[i], TEST_DF_PCS, last); if (p_cmd->cmd_rx) rc |= spi_read(CONF_TEST_SPI, &data, &pcs); if (rc != SPI_OK) return false; if (p_cmd->cmd_rx) p_cmd->data[i] = (uint8_t)data; } return true; }
/** * @brief Nonblocking SPI transmit. * @param dev SPI port to use for transmission * @param buf Buffer to transmit. The sizeof buf's elements are * inferred from dev's data frame format (i.e., are * correctly treated as 8-bit or 16-bit quantities). * @param len Maximum number of elements to transmit. * @return Number of elements transmitted. */ uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { uint32 txed = 0; uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT; while (spi_is_tx_empty(dev) && (txed < len)) { if (byte_frame) { dev->regs->DR = ((const uint8*)buf)[txed++]; } else { dev->regs->DR = ((const uint16*)buf)[txed++]; } } return txed; }
/** * \brief Deselect the given device on the SPI bus. * * Call board chip deselect. * * \param p_spi Base address of the SPI instance. * \param device SPI device. * * \pre SPI device must be selected with spi_select_device() first. */ void spi_deselect_device(Spi *p_spi, struct spi_device *device) { device = device; while (!spi_is_tx_empty(p_spi)) { } // Assert all lines; no peripheral is selected. spi_set_peripheral_chip_select_value(p_spi, NONE_CHIP_SELECT_ID); // Last transfer, so de-assert the current NPCS if CSAAT is set. spi_set_lastxfer(p_spi); }
/** * \brief Send a sequence of bytes to a SPI device * * Received bytes on the SPI bus are discarded. * * \param spi Base address of the SPI instance. * \param data data buffer to write * \param len Length of data * * \pre SPI device must be selected with spi_select_device() first */ status_code_t spi_write_packet(volatile void *spi, const uint8_t *data, size_t len) { while (len) { spi_write_single(spi, *data++); while (!spi_is_tx_empty(spi)) { } len--; } return STATUS_OK; }
/** * @brief Nonblocking SPI transmit. * @param dev SPI port to use for transmission * @param buf Buffer to transmit. The sizeof buf's elements are * inferred from dev's data frame format (i.e., are * correctly treated as 8-bit or 16-bit quantities). * @param len Maximum number of elements to transmit. * @return Number of elements transmitted. */ uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) { uint32 txed = 0; uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT; while ((txed < len)) { while(!spi_is_tx_empty(dev)) ; if (byte_frame) { //spi_tx_reg((((const uint8*)buf)[txed++] & 0X0000) ); dev->regs->DR = ((const uint8*)buf)[txed++]; } else { //spi_tx_reg(((const uint16*)buf)[txed++]); dev->regs->DR = ((const uint16*)buf)[txed++]; } } return txed; }
/** * \brief Deselect the given device on the SPI bus. * * Call board chip deselect. * * \param p_spi Base address of the SPI instance. * \param device SPI device. * * \pre SPI device must be selected with spi_select_device() first. */ void spi_deselect_device(Spi *p_spi, const struct spi_device *device) { uint32_t timeout = SPI_TIMEOUT; while (!spi_is_tx_empty(p_spi)) { if (!timeout--) { return; } } // Last transfer, so de-assert the current NPCS if CSAAT is set. spi_set_lastxfer(p_spi); // Disable the CS line digitalWrite(device->cs, HIGH); // Assert all lines; no peripheral is selected. spi_set_peripheral_chip_select_value(p_spi, NONE_CHIP_SELECT_ID); }
/** * \internal * \brief Helper function to wait for the last send operation to complete */ __always_inline static void ili9341_wait_for_send_done(void) { #if defined(CONF_ILI9341_USART_SPI) # if XMEGA while (!usart_tx_is_complete(CONF_ILI9341_USART_SPI)) { /* Do nothing */ } usart_clear_tx_complete(CONF_ILI9341_USART_SPI); # else /* Wait for TX to complete */ while (!usart_spi_is_tx_empty(CONF_ILI9341_USART_SPI)) { /* Do nothing */ } # endif #elif defined(CONF_ILI9341_SPI) /* Wait for TX to complete */ while (!spi_is_tx_empty(CONF_ILI9341_SPI)) { /* Do nothing */ } #endif }
int cph_deca_spi_read(uint16_t headerLength, const uint8_t *headerBuffer, uint32_t readlength, uint8_t *readBuffer) { status_code_t result = STATUS_OK; uint8_t pcs = DW_CHIP_SELECT; uint16_t data; for(int i = 0; i < headerLength; i++) { spi_write(DW_SPI, headerBuffer[i], 0, 0); spi_read(DW_SPI, &data, &pcs); } for(int i = 0; i < readlength; i++) { if (i == (readlength - 1)) spi_set_lastxfer(DW_SPI); spi_write(DW_SPI, 0xFF, 0, 0); spi_read(DW_SPI, &data, &pcs); readBuffer[i] = data & 0xFF; } while (spi_is_tx_empty(DW_SPI) == 0) ; return result; }
/** * \brief Send data to SPI * * \param data The data to be sent out */ void epd_spi_write (unsigned char Data) { spi_write_single(EPD_SPI_ID, Data); while (!spi_is_tx_empty(EPD_SPI_ID)); }