Hi,
I have an ATSAME70Q21 (144-pin) MCU on my board, which (among other things) is used to drive 3 TLC5971 LED driver ICs. The TLC5971s are essentially shift registers, they don't conform to a particular standard interface (although they can be considered SPI-like given their operating frequency etc.). I've previously driven these driver ICs from other platforms, bit banging the required sequence without issue. The process and construct of the data is very nicely demonstrated here (this example displays a sine wave pattern across the LEDs, but the header and data structure is the relevant/important part).
I'm new to the SAME70 platform, and new to the Atmel Studio/ASF environment altogether. I plan on writing most of the application code at the register level in the near future, but would like to make use of ASF for the time being to confirm various components of the design. As such, I'm trying to make the TWIHS example work in driving these TLC5971 ICs. As I mentioned above, these ICs aren't dependent on a particular interface, so a generic two-wire interface such as TWIHS on the SAME70 should be fine :)
The first of the TLC5971 ICs is connected to TWI1 on the SAME70 (TWD1 on pin 105 and TWCK1 on pin 109). All data is sent to the first IC; the first IC then shifts the data to the second and so on. The ASF TWIHS API to which I will refer below is here.
I've started with the Atmel Studio master TWIHS example project, and trimmed away the bits and pieces I don't need. This is what I've got so far:
#include "asf.h" #include "stdio_serial.h" #include "conf_board.h" /// @cond 0 /**INDENT-OFF**/ #ifdef __cplusplus extern "C" { #endif /**INDENT-ON**/ /// @endcond /** EEPROM Wait Time */ #define WAIT_TIME 10 /** TWI Bus Clock 400kHz */ #define TWIHS_CLK 400000 #if (SAMV70 || SAMV71 || SAME70 || SAMS70) /** TWI ID for simulated EEPROM application to use */ #define I2C_CHANNEL_TLC5971 ID_TWIHS1 /** TWI Base for simulated TWI EEPROM application to use */ #define I2C_BASE_TLC5971 TWIHS1 #endif /** * \brief Configure the Console UART. */ static void configure_console(void) { const usart_serial_options_t uart_serial_options = { .baudrate = CONF_UART_BAUDRATE, #ifdef CONF_UART_CHAR_LENGTH .charlength = CONF_UART_CHAR_LENGTH, #endif .paritytype = CONF_UART_PARITY, #ifdef CONF_UART_STOP_BITS .stopbits = CONF_UART_STOP_BITS, #endif }; /* Configure console UART. */ sysclk_enable_peripheral_clock(CONSOLE_UART_ID); stdio_serial_init(CONF_UART, &uart_serial_options); } /** * \brief Application entry point for TWI EEPROM example. * * \return Unused (ANSI-C compatibility). */ int main(void) { twihs_options_t opt; /* Initialize the SAM system */ sysclk_init(); /* Initialize the board */ board_init(); /* Initialize the console UART */ configure_console(); /* Configure systick for 1 ms */ puts("Configure system tick to get 1ms tick period.\r"); if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { puts("-E- Systick configuration error\r"); while (1) { /* Capture error */ } } /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(I2C_CHANNEL_TLC5971); /* Configure the options of TWI driver */ opt.master_clk = sysclk_get_peripheral_hz(); opt.speed = TWIHS_CLK; uint8_t packets[3][28]; for (int i = 0; i < 3; i++) { long header = 0b10010100010 << (32-6-5); Byte brightness = 0x33; brightness >>= 1; header |= brightness; header |= (long)brightness << 7; header |= (long)brightness << 7*2; packets[i][0] = header >> 8*3; packets[i][1] = header >> 8*2; packets[i][2] = header >> 8; packets[i][3] = header; for (int j = 0; j < 12; j++) { int value = 127; packets[i][j*2 + 4] = value >> 8; packets[i][j*2 + 5] = value; } } if (twihs_master_init(I2C_BASE_TLC5971, &opt) != TWIHS_SUCCESS) { puts("-E-\tTWI master initialization failed.\r"); while (1) { /* Capture error */ } } while(1) { for (int k = 0; k < 28; k++) { twihs_write_byte(I2C_BASE_TLC5971, packets[0][k]); } for (int l = 0; l < 28; l++) { twihs_write_byte(I2C_BASE_TLC5971, packets[1][l]); } for (int m = 0; m < 28; m++) { twihs_write_byte(I2C_BASE_TLC5971, packets[2][m]); } } } /// @cond 0 /**INDENT-OFF**/ #ifdef __cplusplus } #endif /**INDENT-ON**/ /// @endcond
As you can see, I've largely handled the data for each of the 3 TLC5971 ICs individually for the time being. I had initially tried using the twihs_master_write() function, but it included a number of I2C-like parameters which weren't applicable in this case. The twihs_write_byte() function seems more suitable, as it essentially writes the received byte directly to the Transmit Holding Register.
I don't appear to be getting any activity on the TLC5971 ICs but the twihs_master_init() function executes without issue; where have I gone wrong in the above?
Thanks!