void spi_sendToDev(packet_t *pkt) { //cli(); uint8_t len; uint8_t flag = 0xAA; if(pkt) { spi_select_device(SPI_USB, &SPI_DEVICE_USB); SPIC.DATA = flag; while(!spi_is_rx_full(SPI_USB)); spi_write_packet(SPI_USB, &(pkt->len), 1); spi_write_packet(SPI_USB, &(pkt->task), 1); spi_write_packet(SPI_USB, &(pkt->subTask), 1); spi_write_packet(SPI_USB, pkt->buf, pkt->len); spi_deselect_device(SPI_USB, &SPI_DEVICE_USB); } else { LED_On(LED6_GPIO); } sei(); }
/** * \internal * \brief Helper function to read a byte from an arbitrary interface * * This function is used to hide what interface is used by the driver, e.g. * the driver does not need to know if USART in SPI mode is used or the native * SPI module. */ __always_inline static uint8_t hx8347a_read_byte(void) { uint8_t data; #if defined(CONF_HX8347A_USART_SPI) # if UC3 /* A workaround for optimizing data transfer had to be done for the * XMEGA in order for the display to work correctly at all SPI clock * clock speeds */ /* This function could also be used for XMEGA but results in a very slow * framerate, hence a workaround has been implemented for the XMEGA */ usart_spi_read_packet(CONF_HX8347A_USART_SPI, &data, 1); # elif XMEGA usart_spi_read_single(CONF_HX8347A_USART_SPI, &data); # endif #elif defined(CONF_HX8347A_SPI) spi_write_single(CONF_HX8347A_SPI, 0xFF); /* Wait for RX to complete */ while (!spi_is_rx_full(CONF_HX8347A_SPI)) { /* Do nothing */ } spi_read_single(CONF_HX8347A_SPI, &data); #endif return data; }
/** * \internal * \brief Helper function to read a byte from an arbitrary interface * * This function is used to hide what interface is used by the component * driver, e.g. the component driver does not need to know if USART in SPI * mode is used or the native SPI module. * * \retval uint8_t Byte of data read from the display controller */ __always_inline static uint8_t ili9341_read_byte(void) { uint8_t data; #if defined(CONF_ILI9341_USART_SPI) # if XMEGA /* Workaround for clearing the RXCIF for XMEGA */ usart_rx_enable(CONF_ILI9341_USART_SPI); usart_put(CONF_ILI9341_USART_SPI, 0xFF); while (!usart_rx_is_complete(CONF_ILI9341_USART_SPI)) { /* Do nothing */ } data = usart_get(CONF_ILI9341_USART_SPI); /* Workaround for clearing the RXCIF for XMEGA */ usart_rx_disable(CONF_ILI9341_USART_SPI); # else usart_spi_read_single(CONF_ILI9341_USART_SPI, &data); # endif #elif defined(CONF_ILI9341_SPI) spi_write_single(CONF_ILI9341_SPI, 0xFF); ili9341_wait_for_send_done(); /* Wait for RX to complete */ while (!spi_is_rx_full(CONF_ILI9341_SPI)) { /* Do nothing */ } spi_read_single(CONF_ILI9341_SPI, &data); #endif return data; }
/** * \brief Send one byte to a SPI device * * Received byte on the SPI bus is discarded. * * \param spi Base address of the SPI instance. * \param data data to write * * \pre SPI device must be selected with spi_select_device() first */ status_code_t spi_write_once(SPI_t *spi, uint8_t data) { spi_write_single(spi, data); while(!spi_is_rx_full(spi)); return STATUS_OK; }
/** * \brief Receive a single byte from a SPI device * * byte sent out on SPI bus is sent as value 0. * * \param spi Base address of the SPI instance. * * \pre SPI device must be selected with spi_select_device() first */ uint8_t spi_read_once(SPI_t *spi) { uint8_t data; spi_write_single(spi,CONFIG_SPI_MASTER_DUMMY); //Dummy write while(!spi_is_rx_full(spi)); spi_read_single(spi,&data); return data; }
/** * \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 Receive a sequence of bytes from a SPI device * * All bytes sent out on SPI bus are sent as value 0. * * \param spi Base address of the SPI instance. * \param data data buffer to read * \param len Length of data * * \pre SPI device must be selected with spi_select_device() first */ status_code_t spi_read_packet(SPI_t *spi, uint8_t *data, size_t len) { while(len) { spi_write_single(spi,CONFIG_SPI_MASTER_DUMMY); //Dummy write while(!spi_is_rx_full(spi)); spi_read_single(spi,data); len--; data++; } return STATUS_OK; }
/** * \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(SPI_t *spi,const uint8_t *data, size_t len) { size_t i=0; while(len) { spi_write_single(spi,*(data+i)); while(!spi_is_rx_full(spi)); len--; i++; } return STATUS_OK; }
/** * \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(SPI_t *spi, const uint8_t *data, size_t len) { while (len--) { spi_write_single(spi, *data++); while (!spi_is_rx_full(spi)) { } } return STATUS_OK; }
void AT42QT1110_spi_read_timeout(uint8_t* data, uint32_t timeout_us) { uint32_t t = 0; while (!spi_is_rx_full(SPI_TOUCH)) { delay_us(1); if(t++ > timeout_us) return; } t = 0; spi_read_single(&SPI_TOUCH, data); return; }
/** * \brief Receive a sequence of bytes from a SPI device * * All bytes sent out on SPI bus are sent as value 0. * * \param spi Base address of the SPI instance. * \param data data buffer to read * \param len Length of data * * \pre SPI device must be selected with spi_select_device() first */ status_code_t spi_read_packet(volatile void *spi, uint8_t *data, size_t len) { while (len) { spi_write_single(spi, CONFIG_SPI_MASTER_DUMMY); /* Dummy write */ while (!spi_is_rx_full(spi)) { } *data = SPDR; data++; len--; } return STATUS_OK; }
/** * \brief Send a command to the ADS7843 touch controller. * * \param uc_cmd command to send. * * \return Command result. */ static uint32_t ads7843_send_cmd(uint8_t uc_cmd) { uint32_t uResult = 0; volatile uint32_t i; uint8_t data; uint32_t timeout = SPI_TIMEOUT; /* (volatile declaration needed for code optimisation by compiler) */ volatile uint8_t bufferRX[ADS7843_BUFSIZE]; volatile uint8_t bufferTX[ADS7843_BUFSIZE]; bufferRX[0] = 0; bufferRX[1] = 0; bufferRX[2] = 0; bufferTX[0] = uc_cmd; bufferTX[1] = 0; bufferTX[2] = 0; for(i = 0; i < ADS7843_BUFSIZE; i++){ timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(BOARD_ADS7843_SPI_BASE)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } spi_write_single(BOARD_ADS7843_SPI_BASE, bufferTX[i]); } for(i = 0; i < ADS7843_BUFSIZE; i++){ timeout = SPI_TIMEOUT; while (!spi_is_rx_full(BOARD_ADS7843_SPI_BASE)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } spi_read_single(BOARD_ADS7843_SPI_BASE, &data); bufferRX[i] = data; } uResult = (uint32_t)bufferRX[1] << 8; uResult |= (uint32_t)bufferRX[2]; uResult = uResult >> 4; return uResult; }
/** * \ingroup freertos_spi_peripheral_control_group * \brief Initiate a completely asynchronous multi-byte read operation on an SPI * peripheral. * * freertos_spi_read_packet_async() is an ASF specific FreeRTOS driver function. * It configures the SPI peripheral DMA controller (PDC) to read data from the * SPI port, then returns. freertos_spi_read_packet_async() does not wait for * the reception to complete before returning. * * The FreeRTOS ASF SPI driver is initialized using a call to * freertos_spi_master_init(). The freertos_driver_parameters.options_flags * parameter passed into the initialization function defines the driver behavior. * freertos_spi_read_packet_async() can only be used if the * freertos_driver_parameters.options_flags parameter passed to the initialization * function had the WAIT_RX_COMPLETE bit clear. * * freertos_spi_read_packet_async() is an advanced function and readers are * recommended to also reference the application note and examples that * accompany the FreeRTOS ASF drivers. freertos_spi_read_packet() is a version * that does not exit until the PDC transfer is complete, but still allows other * RTOS tasks to execute while the transmission is in progress. * * The FreeRTOS ASF driver both installs and handles the SPI PDC interrupts. * Users do not need to concern themselves with interrupt handling, and must * not install their own interrupt handler. * * \param p_spi The handle to the SPI port returned by the * freertos_spi_master_init() call used to initialise the port. * \param data A pointer to the buffer into which received data is to be * written. * \param len The number of bytes to receive. * \param block_time_ticks The FreeRTOS ASF SPI driver is initialized using a * call to freertos_spi_master_init(). The * freertos_driver_parameters.options_flags parameter passed to the * initialization function defines the driver behavior. If * freertos_driver_parameters.options_flags had the USE_RX_ACCESS_MUTEX bit * set, then the driver will only read from the SPI peripheral if it has * first gained exclusive access to it. block_time_ticks specifies the * maximum amount of time the driver will wait to get exclusive access * before aborting the read operation. Other tasks will execute during any * waiting time. block_time_ticks is specified in RTOS tick periods. To * specify a block time in milliseconds, divide the milliseconds value by * portTICK_RATE_MS, and pass the result in block_time_ticks. * portTICK_RATE_MS is defined by FreeRTOS. * \param notification_semaphore The RTOS task that calls the receive * function exits the receive function as soon as the reception starts. * The data being received by the PDC cannot normally be processed until * after the reception has completed. The PDC interrupt (handled internally * by the FreeRTOS ASF driver) 'gives' the semaphore when the PDC transfer * completes. The notification_semaphore therefore provides a mechanism for * the calling task to know when the PDC has read the requested number of * bytes. The calling task can call standard FreeRTOS functions to block on * the semaphore until the PDC interrupt occurs. Other RTOS tasks will * execute while the the calling task is in the Blocked state. The * semaphore must be created using the FreeRTOS vSemaphoreCreateBinary() API * function before it is used as a parameter. * * \return ERR_INVALID_ARG is returned if an input parameter is invalid. * ERR_TIMEOUT is returned if block_time_ticks passed before exclusive * access to the SPI peripheral could be obtained. STATUS_OK is returned if * the PDC was successfully configured to perform the SPI read operation. */ status_code_t freertos_spi_read_packet_async(freertos_spi_if p_spi, uint8_t *data, uint32_t len, portTickType block_time_ticks, xSemaphoreHandle notification_semaphore) { status_code_t return_value; pdc_packet_t pdc_tx_packet; portBASE_TYPE spi_index; Spi *spi_base; volatile uint16_t junk_value; spi_base = (Spi *) p_spi; spi_index = get_pdc_peripheral_details(all_spi_definitions, MAX_SPIS, (void *) spi_base); /* Don't do anything unless a valid SPI pointer was used. */ if (spi_index < MAX_SPIS) { /* Because the peripheral is half duplex, there is only one access mutex and the rx uses the tx mutex. */ return_value = freertos_obtain_peripheral_access_mutex( &(tx_dma_control[spi_index]), &block_time_ticks); if (return_value == STATUS_OK) { /* Data must be sent for data to be received. Set the receive buffer to all 0xffs so it can also be used as the send buffer. */ memset((void *)data, 0xff, (size_t)len); /* Ensure Rx is already empty. */ while(spi_is_rx_full(all_spi_definitions[spi_index].peripheral_base_address) != 0) { junk_value = ((Spi*) all_spi_definitions[spi_index].peripheral_base_address)->SPI_RDR; (void) junk_value; } /* Start the PDC reception, although nothing is received until the SPI is also transmitting. */ freertos_start_pdc_rx(&(rx_dma_control[spi_index]), data, len, all_spi_definitions[spi_index].pdc_base_address, notification_semaphore); /* Start the transmit so data is also received. */ pdc_tx_packet.ul_addr = (uint32_t)data; pdc_tx_packet.ul_size = (uint32_t)len; pdc_disable_transfer( all_spi_definitions[spi_index].pdc_base_address, PERIPH_PTCR_TXTDIS); pdc_tx_init( all_spi_definitions[spi_index].pdc_base_address, &pdc_tx_packet, NULL); pdc_enable_transfer( all_spi_definitions[spi_index].pdc_base_address, PERIPH_PTCR_TXTEN); /* Catch the end of reception so the access mutex can be returned, and the task notified (if it supplied a notification semaphore). The interrupt can be enabled here because the ENDRX signal from the PDC to the peripheral will have been de-asserted when the next transfer was configured. */ spi_enable_interrupt(spi_base, SPI_IER_ENDRX); return_value = freertos_optionally_wait_transfer_completion( &(rx_dma_control[spi_index]), notification_semaphore, block_time_ticks); } } else { return_value = ERR_INVALID_ARG; } return return_value; }
/** * \brief SPI synchronous read * * \param RDATA The data to be read */ uint8_t epd_spi_read(unsigned char RDATA) { spi_write_single(EPD_SPI_ID, RDATA); /* Dummy write */ while (!spi_is_rx_full(EPD_SPI_ID)) { } return SPDR; }