I'm trying to emulate data from the 10-bit AEAT-6010 rotary encoder and send it out on the MISO pin of the SPI protocol on the ATtiny3217. The ATtiny act as a slave and receive a CLK and SS signal as input to respond to by outputting the data(encoder value). The encoder follows the SSI protocol to send data as shown below:
The problem arrises when trying to send 10 bits voer the 8 bit SPI protocol on the ATtiny. The master of the SPI protocol is the TMS320F2808 chip and from it I receive 11 clock pulses and the SS signal. The measured signals and data is shown below:
Here the data I try to send is 0b10
just for testing. I can see the correct data on the MISO line, but there is three 1's extra in the middle of the signal. This is with BUFEN=1
and BUFWR=1
in the SPI settings of the ATtiny as can be seen in the configuration below(without buffer mode the three 1's comes on the last 3 bits, and aslo the first bit(MSB) is read as a 1):
int8_t SPI_0_init()
{
SPI0.CTRLA = 0 << SPI_CLK2X_bp /* Enable Double Speed: disabled */
| 0 << SPI_DORD_bp /* Data Order Setting: enabled */
| 1 << SPI_ENABLE_bp /* Enable Module: enabled */
| 0 << SPI_MASTER_bp /* SPI module in slave mode */
| SPI_PRESC_DIV4_gc; /* System Clock / 4 */
SPI0.CTRLB = 1 << SPI_BUFEN_bp /* Buffer Mode Enable: enabled */
| 1 << SPI_BUFWR_bp /* Buffer Write Mode: enabled */
| SPI_MODE_0_gc /* SPI Mode 1 */
| 0 << SPI_SSD_bp; /* Slave Select Disable: disabled */
SPI0.INTCTRL = 0 << SPI_DREIE_bp /* Data Register Empty Interrupt Enable: enabled */
| 1 << SPI_IE_bp /* Interrupt Enable: enabled */
| 0 << SPI_RXCIE_bp /* Receive Complete Interrupt Enable: disabled */
| 0 << SPI_SSIE_bp /* Slave Select Trigger Interrupt Enable: disabled */
| 0 << SPI_TXCIE_bp; /* Transfer Complete Interrupt Enable: disabled */
return 0;
}
I have confirmed that the data fromat of the SPI module of the TMS320F2808 and the ATtiny is the same(read on falling clock edge). Is there something I am missing about how the buffers of the SPI work or the interrupts of the SPI? I'm not sure what to to in the ISR when enabling different interrupts(oher than clearing the flags). This is my main function(The ISR is empty for now):
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
sei(); // Enable global interrupts
/* Replace with your application code */
while (1) {
SPI_transmit(enc_data_L);
}
Where the SPI_transmit()
is as follows:
void SPI_transmit(uint16_t enc_data)
{
// Then start the transmission by assigning the data to the SPI data register
SPI0.DATA = enc_data;
//SPI0.DATA = enc_data_H;
// Now wait for the data transmission to complete by periodically checking the SPI status register
//the SPI_IF is the only interrupt flag with a function in non-buffered mode.
while(!(SPI0.INTFLAGS & (SPI_RXCIF_bm)));
SPI0.DATA; //Dummy read to clear flag
}
I have also tried splitting the 16 bit data, as suggested here, but the problem remains also for 8-bit data. Hope this is enough background info. I'm thankful for any ideas!