char CCWrite(char addr, char data) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr); spi_read_single(&SPIC, &stat); spi_write_single(&SPIC, data); spi_deselect_device(&SPIC, &spi_device_conf); return stat; }
char CCRead(char addr, char* data) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr|0x80); spi_read_single(&SPIC, &stat) spi_write_single(&SPIC, CONFIG_SPI_MASTER_DUMMY); spi_read_single(&SPIC, data); spi_deselect_device(&SPIC, &spi_device_conf); return stat; };
/** * \brief Receive a sequence of bytes from an SPI device. * * All bytes sent out on SPI bus are sent as value 0. * * \param p_spi Base address of the SPI instance. * \param data Data buffer to read. * \param len Length of data to be read. * * \pre SPI device must be selected with spi_select_device() first. */ status_code_t spi_read_packet(Spi *p_spi, uint8_t *data, size_t len) { uint32_t timeout = SPI_TIMEOUT; uint8_t val; uint32_t i = 0; while (len) { timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(p_spi)) { if (!timeout--) { return ERR_TIMEOUT; } } spi_write_single(p_spi, CONFIG_SPI_MASTER_DUMMY); timeout = SPI_TIMEOUT; while (!spi_is_rx_ready(p_spi)) { if (!timeout--) { return ERR_TIMEOUT; } } spi_read_single(p_spi, &val); data[i] = val; i++; len--; } return STATUS_OK; }
/** * \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; }
/** * \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 and receive a sequence of bytes from an SPI device. * * \param p_spi Base address of the SPI instance. * \param tx_data Data buffer to send. * \param rx_data Data buffer to read. * \param len Length of data to be read. * * \pre SPI device must be selected with spi_select_device() first. */ spi_status_t spi_transceive_packet(Spi *p_spi, uint8_t *tx_data, uint8_t *rx_data, size_t len) { uint32_t timeout = SPI_TIMEOUT; uint8_t val; uint32_t i = 0; while (len) { timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(p_spi)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } spi_write_single(p_spi, tx_data[i]); timeout = SPI_TIMEOUT; while (!spi_is_rx_ready(p_spi)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } spi_read_single(p_spi, &val); rx_data[i] = val; i++; len--; } return SPI_OK; }
/** * \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; }
/** * \brief Send a sequence of bytes to an SPI device. * * Received bytes on the SPI bus are discarded. * * \param p_spi Base address of the SPI instance. * \param data Data buffer to write. * \param len Length of data to be written. * * \pre SPI device must be selected with spi_select_device() first. */ spi_status_t spi_write_packet(Spi *p_spi, const uint8_t *data, size_t len) { if (len == 0) return SPI_OK; for (size_t i = 0; i < len-1; i++) { uint32_t timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(p_spi)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } p_spi->SPI_TDR = (uint32_t)data[i]; while (!spi_is_rx_ready(p_spi)) { if (!timeout--) { return SPI_ERROR_TIMEOUT; } } p_spi->SPI_RDR; } return spi_write_single(p_spi, data[len-1]); }
/** * \internal * \brief Helper function to send a byte over 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. * * \param data the byte to be transfered */ __always_inline static void hx8347a_send_byte(uint8_t data) { #if defined(CONF_HX8347A_USART_SPI) /* 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 */ # if UC3 usart_spi_write_packet(CONF_HX8347A_USART_SPI, &data, 1); # elif XMEGA usart_spi_write_single(CONF_HX8347A_USART_SPI, data); # endif #elif defined(CONF_HX8347A_SPI) spi_write_single(CONF_HX8347A_SPI, data); /* Wait for TX to complete */ while (!spi_is_tx_ok(CONF_HX8347A_SPI)) { /* Do nothing */ } #endif }
/** * \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 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) { while (len--) { spi_write_single(spi, *data++); while (!spi_is_rx_full(spi)) { } } 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; }
void ENC28J60_WriteOp(uint8_t op, uint8_t address, uint8_t data) { uint8_t cmd; spi_select_device(avr32SPI, &spiDevice); cmd = op | GET_REGISTERADDRESS(address); spi_write_single(avr32SPI, cmd); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } spi_write_single(avr32SPI, data); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } spi_deselect_device(avr32SPI, &spiDevice); }
uint8_t AT42QT1110_send_cmd(uint8_t cmd) { uint8_t data; spi_select_device(SPI_TOUCH, &spi_device_touch); spi_write_single(SPI_TOUCH, cmd); data = AT42QT1110_spi_read_timeout(&data, 100); spi_deselect_device(SPI_TOUCH, &spi_device_touch); return data; }
void ENC28J60_WriteBuffer(uint16_t len, uint8_t* data) { status_code_t ret = STATUS_OK; spi_select_device(avr32SPI, &spiDevice); spi_write_single(avr32SPI, ENC28J60_WRITE_BUF_MEM); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } ret = spi_write_packet(avr32SPI, data, len); spi_deselect_device(avr32SPI, &spiDevice); }
void CS4270_send_data(uint8_t* data, uint8_t length, uint8_t start_reg) { uint8_t i; spi_select_device(SPI_CODEC, &spi_device_codec); spi_write_single(SPI_CODEC, CS4270_ADDRESS_WRITE); if (length > 1) { //If writing to multiple registers, need incr bit spi_write_single(SPI_CODEC, start_reg | (1 << 7)); } else { spi_write_single(SPI_CODEC, start_reg); } for (i=0; i<length; i++) { spi_write_single(SPI_CODEC, data[i]); } spi_deselect_device(SPI_CODEC, &spi_device_codec); }
/** * \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; }
void AT42QT1110_send_data(uint8_t* data, uint8_t length) { uint8_t i; spi_select_device(SPI_TOUCH, &spi_device_touch); for (i=0; i<length; i++) { delay_us(150); spi_write_single(SPI_TOUCH, data[i]); } spi_deselect_device(SPI_TOUCH, &spi_device_touch); return; }
uint8_t CS4270_read_data(void) { uint8_t data; spi_select_device(SPI_CODEC, &spi_device_codec); spi_write_single(SPI_CODEC, CS4270_ADDRESS_READ); spi_read_single(SPI_CODEC, &data); spi_deselect_device(SPI_CODEC, &spi_device_codec); return data; }
char CCWriteBurst(char addr, const char* dataPtr, char size) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr|0x40); spi_read_single(&SPIC, &stat); spi_write_packet(&SPIC, *dataPtr, size); spi_deselect_device(&SPIC, &spi_device_conf); return stat; }
/** * \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; }
status_code_t spi_write_packet(volatile avr32_spi_t *spi, const uint8_t *data, size_t len) { unsigned int timeout = SPI_TIMEOUT; size_t i=0; uint8_t val; while(len) { timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(spi)) { if (!timeout--) { return ERR_TIMEOUT; } } val = data[i]; spi_write_single(spi,val); i++; len--; } return STATUS_OK; }
void AT42QT1110_get_data(uint8_t cmd, uint8_t* data, uint8_t length) { uint8_t idle; uint8_t i; spi_select_device(SPI_TOUCH, &spi_device_touch); idle = AT42QT1110_send_cmd(cmd); if (idle != 0x55) return; for (i=0; i<length; i++) { delay_us(150); spi_write_single(SPI_TOUCH, 0x00); AT42QT1110_spi_read_timeout(data, 100); } spi_deselect_device(SPI_TOUCH, &spi_device_touch); return; }
/** * \brief Send a sequence of bytes to an SPI device. * * Received bytes on the SPI bus are discarded. * * \param p_spi Base address of the SPI instance. * \param data Data buffer to write. * \param len Length of data to be written. * * \pre SPI device must be selected with spi_select_device() first. */ status_code_t spi_write_packet(Spi *p_spi, const uint8_t *data, size_t len) { uint32_t timeout = SPI_TIMEOUT; uint32_t i = 0; uint8_t val; while (len) { timeout = SPI_TIMEOUT; while (!spi_is_tx_ready(p_spi)) { if (!timeout--) { return ERR_TIMEOUT; } } val = data[i]; spi_write_single(p_spi, val); i++; len--; } return STATUS_OK; }
/** * \internal * \brief Helper function to send a byte over 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. * * \param data The byte to be transfered */ __always_inline static void ili9341_send_byte(uint8_t data) { #if defined(CONF_ILI9341_USART_SPI) # if XMEGA while (!usart_data_register_is_empty(CONF_ILI9341_USART_SPI)) { /* Do nothing */ } irqflags_t flags = cpu_irq_save(); usart_clear_tx_complete(CONF_ILI9341_USART_SPI); usart_put(CONF_ILI9341_USART_SPI, data); cpu_irq_restore(flags); # else usart_spi_write_single(CONF_ILI9341_USART_SPI, data); # endif #elif defined(CONF_ILI9341_SPI) /* Wait for any previously running send data */ ili9341_wait_for_send_done(); spi_write_single(CONF_ILI9341_SPI, data); #endif }
/** * \internal * \brief Initialize the hardware interface to the controller * * This will initialize the module used for communication with the controller. * Currently supported interfaces by this component driver are the SPI * interface through either the SPI module in master mode or the USART in * Master SPI mode. Configuration must be done in the associated * conf_ili9341.h file. */ static void ili9341_interface_init(void) { #if defined(CONF_ILI9341_USART_SPI) || defined(CONF_ILI9341_SPI) spi_flags_t spi_flags = SPI_MODE_0; board_spi_select_id_t spi_select_id = 0; #else #error Interface for ILI9341 has not been selected or interface not\ supported, please configure component driver using the conf_ili9341.h\ file! #endif #if defined(CONF_ILI9341_USART_SPI) struct usart_spi_device device = { .id = 0, }; usart_spi_init(CONF_ILI9341_USART_SPI); usart_spi_setup_device(CONF_ILI9341_USART_SPI, &device, spi_flags, CONF_ILI9341_CLOCK_SPEED, spi_select_id); #elif defined(CONF_ILI9341_SPI) struct spi_device device = { .id = 0, }; spi_master_init(CONF_ILI9341_SPI); spi_master_setup_device(CONF_ILI9341_SPI, &device, spi_flags, CONF_ILI9341_CLOCK_SPEED, spi_select_id); spi_enable(CONF_ILI9341_SPI); # if UC3 spi_set_chipselect(CONF_ILI9341_SPI, ~(1 << 0)); # if defined(ILI9341_DMA_ENABLED) sysclk_enable_peripheral_clock(&AVR32_PDCA); # endif # endif /* Send one dummy byte for the spi_is_tx_ok() to work as expected */ spi_write_single(CONF_ILI9341_SPI, 0); #endif } /** * \internal * \brief Initialize all the display registers * * This function will set up all the internal registers according the the * manufacturer's description. */ static void ili9341_controller_init_registers(void) { ili9341_send_command(ILI9341_CMD_POWER_CONTROL_A); ili9341_send_byte(0x39); ili9341_send_byte(0x2C); ili9341_send_byte(0x00); ili9341_send_byte(0x34); ili9341_send_byte(0x02); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_POWER_CONTROL_B); ili9341_send_byte(0x00); ili9341_send_byte(0xAA); ili9341_send_byte(0XB0); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_PUMP_RATIO_CONTROL); ili9341_send_byte(0x30); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_POWER_CONTROL_1); ili9341_send_byte(0x25); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_POWER_CONTROL_2); ili9341_send_byte(0x11); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_VCOM_CONTROL_1); ili9341_send_byte(0x5C); ili9341_send_byte(0x4C); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_VCOM_CONTROL_2); ili9341_send_byte(0x94); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_DRIVER_TIMING_CONTROL_A); ili9341_send_byte(0x85); ili9341_send_byte(0x01); ili9341_send_byte(0x78); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_DRIVER_TIMING_CONTROL_B); ili9341_send_byte(0x00); ili9341_send_byte(0x00); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_send_command(ILI9341_CMD_COLMOD_PIXEL_FORMAT_SET); ili9341_send_byte(0x05); ili9341_wait_for_send_done(); ili9341_deselect_chip(); ili9341_set_orientation(0); ili9341_set_limits(0, 0, ILI9341_DEFAULT_WIDTH, ILI9341_DEFAULT_HEIGHT); } /** * \internal * \brief Send display commands to exit standby mode * * This function is used to exit the display standby mode, which is the default * mode after a reset signal to the display. */ static void ili9341_exit_standby(void) { ili9341_send_command(ILI9341_CMD_SLEEP_OUT); ili9341_deselect_chip(); delay_ms(150); ili9341_send_command(ILI9341_CMD_DISPLAY_ON); ili9341_deselect_chip(); }
/** * \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; }
/** * \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)); }