SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

Hi, I am trying to operate a SPI interface on SAM4S-EK.
Can someone tell me why when I am using this function: 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%xn”,(*p_buffer32) );
puts(str);
} Using only Atmels’ SPI driver, everything works OK.
But, when I am using the next function, using the FreeRTOS (7.3.0) SPI API,
The ‘freertos_spi_read_packet’ doesn’t return, instead I get to ‘Dummy_Handler’ indicating some exception occurred…   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);
uint8_t  *p_buffer;
uint32_t *p_buffer32;
uint8_t  *str; p_buffer   = p_buf;
p_buffer32 = p_buf; returned_status = freertos_spi_write_packet(freertos_spi, p_buffer, size, time_out_definition);
sprintf( str, “SPI master sent: 0x%x”,(*p_buffer32) );
puts(str);
returned_status = freertos_spi_read_packet(freertos_spi, p_buffer, size, time_out_definition);
sprintf( str, “SPI master received: 0x%xn”,(*p_buffer32) );
puts(str);
} I appreciate your help. Thanks,
Assaf
_

SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

The Atmel ASF includes working examples for the FreeRTOS ASF SPI functions – and an application note.  Have you tried using those? In this case:
- Have you created the SPI port using a call to freertos_spi_master_init()?  That should install the interrupt handler.
- If you have called freertos_spi_master_init() please determine which interrupt is being called (dummy_handler is installed on all unused interrupts I think).  Knowing which interrupt is executing will help track down why the interrupt is being triggered. Regards.

SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

Thank you for your reply.
1. Actually the ASF peripheral example does not contain SPI for SAM4S-EK, Anyway, as I follow the FreeRTOS API description, this code of mine, should work…
2. I did use the  freertos_spi_master_init(), sorry for no mentioning it before.
3. So back to the original problem – I found the reason the freertos_spi_read_packet has crashed, Now I can’t understand why it doesn’t operate has expected:
I have a SPI slave device that return the 32bit of data it receives.
With Atmels’ driver only, I do see that I get back the data that I send: 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%xn”,(*p_buffer32) );
puts(str);
} But using FreeRTOS API, I receive all kind of mixed data… 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);
} I mean, I call this function couple of times.
I expect to read on the second time, the data I wrote the first time. Nothing else but this function has changed in the program, and the slave device is the same too… Can someone explain me why?… Thanks,
Assaf
_

SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

In this code you are clocking out SPI data then clocking in SPI data and expecting to receive what you sent. Is that correct? If so, I guess you have the SPI set into loopback mode, which I doubt the FreeRTOS driver does.

SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

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 masterrn”); 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%xn”,(*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_

SPI with Atmel SAM4S-EK and FreeRTOS 7.3.0

Without being able to try this myself at the moment I’m not sure what to suggest. 
Actually the ASF peripheral example does not contain SPI for SAM4S-EK, Anyway, as I follow the FreeRTOS API description, this code of mine, should work…
You can find an example in the thirdpartyfreertosdemoperipheral_controldemo-tasksSPI-FLASH-task.c file.  It might be that it is not included in the SAM4S-EK demo project because the SAM4S-EK does not include the same SPI flash as found on other EK boards but reviewing the code there may still assist. Regards.