goldie13 wrote on Wednesday, April 24, 2013:
Hi,
No. I am not using SPI loopback mode.
My setup include two devices, the SAM4S-EK set as SPI master and another device set to SPI slave. I am using Chip-Select 0.
The SPI slave device writes back the data it receives.
I am working on the SAM4S-EK master device.
Here is my master init function:
static void spi_master_initialize(void)
{
freertos_peripheral_options_t driver_options = { receive_buffer, /* The buffer used internally by the SPI driver to store incoming characters. */
RX_BUFFER_SIZE, /* The size of the buffer provided to the SPI driver to store incoming characters. */
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, /* The priority used by the SPI interrupts. */
SPI_MASTER, /* Configure the SPI for master. */
(USE_TX_ACCESS_MUTEX | USE_RX_ACCESS_MUTEX | WAIT_TX_COMPLETE | WAIT_RX_COMPLETE)
};
puts("- Initialize SPI as master\r\n");
freertos_spi = freertos_spi_master_init(SPI_MASTER_BASE, &driver_options);
spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL);
spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL, (sysclk_get_cpu_hz() / gs_ul_spi_clock));
spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT);
spi_configure_cs_behavior(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CS_KEEP_LOW);
spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL);
spi_enable(SPI_MASTER_BASE);
}
Here is the slave init function:
static void spi_slave_initialize(void)
{
puts("- Initialize SPI as slave \r");
/* Configure an SPI peripheral. */
spi_enable_clock(SPI_SLAVE_BASE);
spi_disable(SPI_SLAVE_BASE);
spi_reset(SPI_SLAVE_BASE);
spi_set_slave_mode(SPI_SLAVE_BASE);
spi_disable_mode_fault_detect(SPI_SLAVE_BASE);
spi_set_peripheral_chip_select_value(SPI_SLAVE_BASE, SPI_CHIP_SEL);
spi_set_clock_polarity(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
spi_set_clock_phase(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
spi_set_bits_per_transfer(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
spi_enable_interrupt(SPI_SLAVE_BASE, SPI_IER_RDRF);
spi_enable(SPI_SLAVE_BASE);
/* Start waiting command. */
spi_slave_transfer();
}
Now, I am transmitting and receiving 32 bits of data.
I repeat this couple of times, let’s say three times:
for( i = 0 ; i < 3 ; i++ )
{
cmd = ul_cmd_list_;
spi_master_transfer(&cmd, sizeof(cmd));
}
I expect that on the first time, I’ll write 32bits of data, and read zero’s or some junk…
On the second time, I’ll write another 32bits of data, and receive back the 32bits I wrote the first time…
On the third time, I’ll write another 32bits of data, and receive back the 32bits I wrote the second time…
So again, when I am using transfer function option 1 (below), with clean Atmel’s driver everything works as expected,
But when I am using transfer function option 2, I get back mixed data and junk…
Nothing else but the transfer function was changed in the configuration… The slave device wasn’t changed at all and in the master I replaced only the transfer function to option 2…
Can you explain me the difference…?
Is it something related to ‘spi_set_bits_per_transfer(…)’ configuration? It should be the same for both master and slave, right?
Can you explain me what’s wrong?
Option 1:
static void spi_master_transfer(void *p_buf, uint32_t size)
{
uint32_t i;
uint8_t uc_pcs;
static uint16_t data;
uint8_t *p_buffer;
uint32_t *p_buffer32;
uint8_t *str;
p_buffer = p_buf;
p_buffer32 = p_buf;
sprintf( str, “SPI master sent: 0x%x”,(*p_buffer32) );
puts(str);
for (i = 0; i < size; i++)
{
spi_write(SPI_MASTER_BASE, p_buffer, 0, 0);
/* Wait transfer done. */
while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
spi_read(SPI_MASTER_BASE, &data, &uc_pcs);
p_buffer = data;
}
sprintf( str, “SPI master received: 0x%x\n”,(*p_buffer32) );
puts(str);
}
Option2:
static void spi_master_transfer(void *p_buf, uint32_t size)
{
status_code_t returned_status;
const portTickType time_out_definition = (100UL / portTICK_RATE_MS);
uint32_t data32_tx, data32_rx;
memcpy(&data32_tx, p_buf, sizeof(data32_tx));
returned_status = freertos_spi_write_packet(freertos_spi, &data32_tx, sizeof(data32_tx), time_out_definition);
memset(&data32_rx, 0, sizeof(data32_rx));
returned_status = freertos_spi_read_packet(freertos_spi, &data32_rx, sizeof(data32_rx), time_out_definition);
}
Thanks,
Assaf_