MCUXpresso_LPC55S69/boards/lpcxpresso55s69/azure_rtos_examples/spi_example/cm33_core0/spi_example.c
2022-04-08 22:42:47 +08:00

229 lines
5.6 KiB
C

#include <string.h>
#include "fsl_common.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "board_setup.h"
#include "tx_api.h"
#include "tx_spi.h"
#define DATA_LENGTH (32)
#define DEMO_STACK_SIZE (4 * 1024)
static uint8_t master_tx_buffer[DATA_LENGTH];
static uint8_t master_rx_buffer[DATA_LENGTH];
static uint8_t slave_tx_buffer[DATA_LENGTH];
static uint8_t slave_rx_buffer[DATA_LENGTH];
static TX_THREAD demo_master_thread;
static TX_THREAD demo_slave_thread;
static ULONG demo_stack_master[DEMO_STACK_SIZE / sizeof(ULONG)];
static ULONG demo_stack_slave[DEMO_STACK_SIZE / sizeof(ULONG)];
static tx_spi_master_context_t master_context;
static tx_spi_slave_context_t slave_context;
static TX_SEMAPHORE sync_semaphore;
static TX_MUTEX print_lock;
static void print_array(uint8_t *buffer, uint32_t size)
{
UINT status;
int i;
status = tx_mutex_get(&print_lock, TX_WAIT_FOREVER);
if (status != TX_SUCCESS)
{
return;
}
for (i = 0; i < size; i++)
{
if ((i % 8 == 0) && (i != 0))
{
PRINTF("\r\n");
}
PRINTF("0x%1x%1x ", buffer[i] >> 4, buffer[i] & 0x0f);
}
PRINTF("\r\n");
tx_mutex_put(&print_lock);
}
static VOID demo_master_thread_entry(ULONG arg)
{
int result;
UINT status;
UINT i;
TX_THREAD_NOT_USED(arg);
status = tx_init_spi_master(&master_context);
if (status != TX_SUCCESS)
{
PRINTF("ERR: tx_init_spi_master() -> 0x%x\r\n", status);
return;
}
for (i = 0U; i < DATA_LENGTH; i++)
{
master_tx_buffer[i] = i % 256;
}
memset(master_rx_buffer, 0, DATA_LENGTH);
/* start to transfer data after the slave side is ready */
status = tx_semaphore_get(&sync_semaphore, TX_WAIT_FOREVER);
assert(status == TX_SUCCESS);
status = tx_spi_master_transfer(&master_context, master_tx_buffer,
master_rx_buffer, DATA_LENGTH);
if (status != TX_SUCCESS)
{
PRINTF("ERR: tx_spi_master_transfer() -> 0x%x\r\n", status);
return;
}
PRINTF("Master transmited:\r\n");
print_array(master_tx_buffer, DATA_LENGTH);
PRINTF("\r\n");
PRINTF("Slave received:\r\n");
print_array(slave_rx_buffer, DATA_LENGTH);
PRINTF("\r\n");
PRINTF("Slave transmited:\r\n");
print_array(slave_tx_buffer, DATA_LENGTH);
PRINTF("\r\n");
PRINTF("Master received:\r\n");
print_array(master_rx_buffer, DATA_LENGTH);
PRINTF("\r\n");
result = memcmp(master_tx_buffer, slave_rx_buffer, DATA_LENGTH);
if (result == 0)
{
PRINTF("Master-to-slave data verified ok.\r\n");
}
else
{
PRINTF("Mismatch in master-to-slave data!\r\n");
}
result = memcmp(slave_tx_buffer, master_rx_buffer, DATA_LENGTH);
if (result == 0)
{
PRINTF("Slave-to-master data verified ok.\r\n");
}
else
{
PRINTF("Mismatch in slave-to-master data!\r\n");
}
}
static VOID demo_slave_thread_entry(ULONG arg)
{
UINT status;
UINT i;
TX_THREAD_NOT_USED(arg);
status = tx_init_spi_slave(&slave_context);
if (status != TX_SUCCESS)
{
PRINTF("ERR: tx_init_spi_slave() -> 0x%x\r\n", status);
return;
}
for (i = 0U; i < DATA_LENGTH; i++)
{
slave_tx_buffer[i] = ~(i % 256);
}
memset(slave_rx_buffer, 0, DATA_LENGTH);
status = tx_mutex_get(&slave_context.lock, TX_WAIT_FOREVER);
assert(status == TX_SUCCESS);
status = tx_spi_slave_transfer(&slave_context, slave_tx_buffer,
slave_rx_buffer, DATA_LENGTH);
if (status != TX_SUCCESS)
{
tx_mutex_put(&slave_context.lock);
PRINTF("ERR: tx_spi_slave_transfer() -> 0x%x\r\n", status);
return;
}
/* signal that the slave side is ready */
status = tx_semaphore_put(&sync_semaphore);
assert(status == TX_SUCCESS);
/* wait for tranfer completion */
status = tx_semaphore_get(&slave_context.sema_sync, TX_WAIT_FOREVER);
assert(status == TX_SUCCESS);
if (slave_context.result != SPI_SLAVE_RETURN_OK)
{
PRINTF("ERR: SPI communication error, %d\r\n", slave_context.result);
}
tx_mutex_put(&slave_context.lock);
}
void tx_application_define(void *first_unused_memory)
{
UINT status;
TX_THREAD_NOT_USED(first_unused_memory);
status = tx_mutex_create(&print_lock, "PRINT LOCK", TX_NO_INHERIT);
if (status != TX_SUCCESS)
{
PRINTF("ERR: create the print_lock mutex\r\n");
return;
}
status = tx_semaphore_create(&sync_semaphore, "SYNC", 0);
if (status != TX_SUCCESS)
{
PRINTF("ERR: create the sync_semaphore semaphore\r\n");
return;
}
status = tx_thread_create(&demo_slave_thread, "slave thread",
demo_slave_thread_entry, 0,
(VOID *)demo_stack_slave, DEMO_STACK_SIZE,
15, 15, 1, TX_AUTO_START);
if (status != TX_SUCCESS)
{
PRINTF("ERR: create the demo_slave_thread thread, 0x%x\r\n", status);
return;
}
status = tx_thread_create(&demo_master_thread, "master thread",
demo_master_thread_entry, 0,
(VOID *)demo_stack_master, DEMO_STACK_SIZE,
15, 15, 1, TX_AUTO_START);
if (status != TX_SUCCESS)
{
PRINTF("ERR: create the demo_master_thread thread, 0x%x\r\n", status);
return;
}
}
int main(void)
{
board_setup();
PRINTF("\r\nStart the SPI example\r\n\r\n");
/* Enter the ThreadX kernel. */
tx_kernel_enter();
return 0;
}