17 #if !defined(MBED_CONF_APP_SPI_MASTER_MISO) || \    18     !defined(MBED_CONF_APP_SPI_MASTER_MOSI) || \    19     !defined(MBED_CONF_APP_SPI_MASTER_CLK) || \    20     !defined(MBED_CONF_APP_SPI_MASTER_SS) || \    21     !defined(MBED_CONF_APP_SPI_MASTER_HALF_DUPLEX_DATA) || \    22     !defined(MBED_CONF_APP_SPI_MASTER_SS_ACTIVE_HIGH) || \    23     !defined(MBED_CONF_APP_SPI_MASTER_DELAY) || \    24     !defined(MBED_CONF_APP_SPI_SLAVE_MISO) || \    25     !defined(MBED_CONF_APP_SPI_SLAVE_MOSI) || \    26     !defined(MBED_CONF_APP_SPI_SLAVE_CLK) || \    27     !defined(MBED_CONF_APP_SPI_SLAVE_SS) || \    28     !defined(MBED_CONF_APP_SPI_SLAVE_HALF_DUPLEX_DATA) || \    29     !defined(MBED_CONF_APP_SPI_SLAVE_DELAY)    30 #error [NOT_SUPPORTED] Configuration not found!    33 #define DEFAULT_TEST_SYM_CNT 5    34 #define SHORTER_TEST_SYM_CNT 3    35 #define SHORTEST_TEST_SYM_CNT 1    36 #define LONG_TEST_SYM_CNT 64    38 #define FREQ_200KHZ (200000)    39 #define FREQ_1MHZ   (1000000)    40 #define FREQ_2MHZ   (2000000)    43 #define US_PER_MS   (1000)    44 #define US_PER_S    (1000000)    46 #define MASTER_SYNC_BIT_MASK 1    47 #define SLAVE_SYNC_BIT_MASK 2    49 #define MASTER_SPI_MISO MBED_CONF_APP_SPI_MASTER_MISO    50 #define MASTER_SPI_MOSI MBED_CONF_APP_SPI_MASTER_MOSI    51 #define MASTER_SPI_CLK MBED_CONF_APP_SPI_MASTER_CLK    52 #define MASTER_SPI_SS MBED_CONF_APP_SPI_MASTER_SS    53 #define MASTER_SPI_HF_DATA MBED_CONF_APP_SPI_MASTER_HALF_DUPLEX_DATA    54 #define MASTER_SPI_SS_ACTIVE_HIGH MBED_CONF_APP_SPI_MASTER_SS_ACTIVE_HIGH    55 #define MASTER_TRANSMISSION_DELAY_MS MBED_CONF_APP_SPI_MASTER_DELAY    57 #define SLAVE_SPI_MISO MBED_CONF_APP_SPI_SLAVE_MISO    58 #define SLAVE_SPI_MOSI MBED_CONF_APP_SPI_SLAVE_MOSI    59 #define SLAVE_SPI_CLK MBED_CONF_APP_SPI_SLAVE_CLK    60 #define SLAVE_SPI_SS MBED_CONF_APP_SPI_SLAVE_SS    61 #define SLAVE_SPI_HF_DATA MBED_CONF_APP_SPI_SLAVE_HALF_DUPLEX_DATA    62 #define SLAVE_TRANSMISSION_DELAY_MS MBED_CONF_APP_SPI_SLAVE_DELAY    63 #define SLAVE_TRANSMISSION_DELAY_MASTER_MS MBED_CONF_APP_SPI_MASTER_DELAY    65 #define TEST_CAPABILITY_BIT(MASK, CAP) ((1 << CAP) & (MASK))    67 #define DEBUG MBED_CONF_APP_SPI_DEBUG    69 #if(MASTER_SPI_SS_ACTIVE_HIGH)    92     SPI_BUFFERS_MASTER_TX_GT_RX,
    93     SPI_BUFFERS_MASTER_TX_LT_RX,
    94     SPI_BUFFERS_SLAVE_TX_GT_RX,
    95     SPI_BUFFERS_SLAVE_TX_LT_RX,
   106     uint32_t master_tx_cnt;
   107     uint32_t master_rx_cnt;
   108     uint32_t slave_tx_cnt;
   109     uint32_t slave_rx_cnt;
   110     bool master_tx_defined;
   111     bool master_rx_defined;
   112     bool slave_tx_defined;
   113     bool slave_rx_defined;
   130 void init_transmission_buffers_master(
config_test_case_t *config, T *p_tx_pattern, T *p_rx1_pattern, T *p_rx2_pattern,
   131                                       T *p_tx_buff, T *p_rx_buff, T *p_fill_symbol);
   134 void init_transmission_buffers_slave(
config_test_case_t *config, T *p_tx_pattern, T *p_rx1_pattern, T *p_rx2_pattern,
   135                                      T *p_tx_buff, T *p_rx_buff, T *p_fill_symbol);
   138 static uint32_t sym_count = 0;
   141 static volatile bool transfer_finished;
   144 static Semaphore transm_sem(0, 1);
   147 static void transm_timeout_handler()
   149     transm_sem.release();
   153 static void msg_insert_symbol(uint8_t *buffer, uint8_t *symbol_str)
   155     sprintf((
char *) buffer, 
" %s", (
char *) symbol_str);
   160 static void mgs_init(uint8_t *buffer, T *symbols, 
const char *dut, 
const char *buf_name)
   162     uint8_t *p_buffer = buffer;
   165     sprintf((
char *) buffer, 
"%s %s", dut, buf_name);
   166     p_buffer += strlen((
const char *) buffer);
   168     for (uint32_t i = 0; i < sym_count; i++) {
   169         sprintf((
char *) symbol, 
"0x%X", symbols[i]);
   171         msg_insert_symbol(p_buffer, symbol);
   172         p_buffer += (strlen((
const char *) symbol) + 1);
   175     sprintf((
char *) p_buffer, 
"%s", 
"\r\n");
   180 static void dump_buffers(target_t target, T *tx_pattern, T *rx1_pattern, T *rx2_pattern, T *tx_buff, T *rx_buff)
   183     uint8_t buffer[1024];
   186     if (target == MASTER) {
   189         strcpy((
char *)dut, 
"master");
   191         strcpy((
char *)dut, 
"slave");
   194     printf(
"%s - buffers dump: \r\n", dut);
   195     mgs_init<T>(buffer, rx1_pattern, (
const char *)dut, 
"rx1 pattern:");
   196     printf((
const char *)buffer);
   197     mgs_init<T>(buffer, rx2_pattern, (
const char *)dut, 
"rx2 pattern:");
   198     printf((
const char *)buffer);
   199     mgs_init<T>(buffer, tx_buff, (
const char *)dut, 
"tx buffer:  ");
   200     printf((
const char *)buffer);
   201     mgs_init<T>(buffer, rx_buff, (
const char *)dut, 
"rx buffer:  ");
   202     printf((
const char *)buffer);
   210     printf(
"TEST CONFIGURATION\r\n");
   211     printf(
"symbol_size:       %lu\r\n", (uint32_t) config->symbol_size);
   212     printf(
"spi_mode:          %lu\r\n", (uint32_t) config->mode);
   213     printf(
"bit_ordering:      %lu\r\n", (uint32_t) config->bit_ordering);
   214     printf(
"freq:              %lu\r\n", (uint32_t) config->freq_hz);
   215     printf(
"master tx cnt:     %lu\r\n", (uint32_t) config->master_tx_cnt);
   216     printf(
"master rx cnt:     %lu\r\n", (uint32_t) config->master_rx_cnt);
   217     printf(
"slave tx cnt:      %lu\r\n", (uint32_t) config->slave_tx_cnt);
   218     printf(
"slave rx cnt:      %lu\r\n", (uint32_t) config->slave_rx_cnt);
   219     printf(
"master tx defined: %lu\r\n", (uint32_t) config->master_tx_defined);
   220     printf(
"master rx defined: %lu\r\n", (uint32_t) config->master_rx_defined);
   221     printf(
"slave tx defined:  %lu\r\n", (uint32_t) config->slave_tx_defined);
   222     printf(
"slave rx defined:  %lu\r\n", (uint32_t) config->slave_rx_defined);
   223     printf(
"auto ss:           %lu\r\n", (uint32_t) config->auto_ss);
   224     printf(
"duplex:            %lu\r\n", (uint32_t) config->duplex);
   225     printf(
"master sync mode:  %lu\r\n", (uint32_t) config->master_sync);
   226     printf(
"slave sync mode:   %lu\r\n", (uint32_t) config->slave_sync);
   231 static void set_buffer(
void *addr, uint32_t size, uint8_t val)
   233     char *p_char = (
char *) addr;
   235     for (uint32_t i = 0; i < size; i++) {
   248 static void init_buffer_with_pattern(
void *p_buffer, uint32_t sym_count, uint32_t sym_size, uint8_t *p_pattern,
   249                                      uint32_t pattern_sym_count)
   251     uint32_t pattern_idx = 0;
   254         set_buffer(p_buffer, sym_size, p_pattern[pattern_idx]);
   256         p_buffer += sym_size;
   259         if (pattern_idx == pattern_sym_count) {
   268 static void handle_ss(DigitalOut *ss, 
bool select)
   279 #ifdef DEVICE_SPI_ASYNCH   281 static uint32_t context;
   282 static volatile bool async_transm_done;
   283 static volatile uint32_t async_transfered;
   286     async_transm_done = 
true;
   287     async_transfered = 
event->transfered;
   302     if ((!TEST_CAPABILITY_BIT(capabilities.
word_length, (tc_config->symbol_size - 1))) ||
   303             (!TEST_CAPABILITY_BIT(capabilities.
clk_modes, tc_config->mode)) ||
   304             (!TEST_CAPABILITY_BIT(capabilities.
bit_order, tc_config->bit_ordering)) ||
   306             (tc_config->freq_hz != FREQ_MAX && tc_config->freq_hz != FREQ_MIN && tc_config->freq_hz < capabilities.
minimum_frequency && tc_config->freq_hz > capabilities.
maximum_frequency) ||
   307             (!slave && !tc_config->master_sync && !capabilities.
async_mode) ||
   308             (slave && !tc_config->slave_sync && !capabilities.
async_mode) ||
   309             (tc_config->duplex == HALF_DUPLEX && !capabilities.
half_duplex) ||
   310             (!slave && tc_config->auto_ss && !capabilities.
hw_cs_handle)
   313             printf(
"SKIP: Configuration not supported by master.\r\n");
   315             printf(
"SKIP: Configuration not supported by slave.\r\n");
   323 static uint32_t sync_async_transfer(spi_t *obj, 
const void *tx, uint32_t tx_len, 
void *rx, uint32_t rx_len,
   324                                     const void *fill_symbol, 
bool sync_mode)
   329         count = 
spi_transfer(obj, tx, tx_len, rx, rx_len, fill_symbol);
   331 #ifdef DEVICE_SPI_ASYNCH   333         async_transm_done = 
false;
   334         async_transfered = 0;
   336         spi_transfer_async(obj, tx, tx_len, rx, rx_len, fill_symbol, spi_async_callback, &context, DMA_USAGE_NEVER);
   339         while (!async_transm_done) {
   342         count = async_transfered;
   356 static void wait_before_transmission(target_t target)
   358     if (target == MASTER) {
   359         wait_ms(MASTER_TRANSMISSION_DELAY_MS);
   361         wait_ms(SLAVE_TRANSMISSION_DELAY_MS);
   368 static bool check_buffers(
void *p_pattern, 
void *p_buffer, uint32_t size)
   370     const char *p_byte_pattern = (
const char *) p_pattern;
   371     const char *p_byte_buffer = (
const char *) p_buffer;
   373     if (p_buffer == NULL || p_pattern == NULL) {
   378         if (*p_byte_pattern != *p_byte_buffer) {
   398 static int perform_transfer(target_t target, spi_t *obj, 
config_test_case_t *config, DigitalOut *ss)
   405     T *tx_pattern = 
new T[sym_count];
   406     T *rx1_pattern = 
new T[sym_count];
   407     T *rx2_pattern = 
new T[sym_count];
   408     T *tx_buff = 
new T[sym_count];
   409     T *rx_buff = 
new T[sym_count];
   412     void *p_tx_buff = tx_buff;
   413     void *p_rx_buff = rx_buff;
   415     uint32_t clocked_symbols_1 = sym_count;
   416     uint32_t clocked_symbols_2 = sym_count;
   418     if (config->duplex != FULL_DUPLEX) {
   419         if (target == MASTER) {
   420             clocked_symbols_1 = (config->master_tx_cnt + config->master_rx_cnt);
   422             clocked_symbols_1 = (config->slave_tx_cnt + config->slave_rx_cnt);
   425         clocked_symbols_2 = (sym_count + sym_count);
   428     if (target == MASTER) {
   429         if (!config->master_tx_defined) {
   433         if (!config->master_rx_defined) {
   436         sync = config->master_sync;
   438         if (!config->slave_tx_defined) {
   442         if (!config->slave_rx_defined) {
   445         sync = config->slave_sync;
   448     if (target == MASTER) {
   449         init_transmission_buffers_master<T>(config, &tx_pattern[0], &rx1_pattern[0], &rx2_pattern[0], &tx_buff[0], &rx_buff[0],
   452         init_transmission_buffers_slave<T>(config, &tx_pattern[0], &rx1_pattern[0], &rx2_pattern[0], &tx_buff[0], &rx_buff[0],
   457     wait_before_transmission(target);
   459     if (target == MASTER) {
   461         count = sync_async_transfer(obj, p_tx_buff, config->master_tx_cnt, p_rx_buff, config->master_rx_cnt, (
void *) &fill_symbol, sync);
   462         handle_ss(ss, 
false);
   464         count = sync_async_transfer(obj, p_tx_buff, config->slave_tx_cnt, p_rx_buff, config->slave_rx_cnt,
   465                                     (
void *) &fill_symbol, sync);
   468     if (!check_buffers(rx1_pattern, p_rx_buff, 
sizeof(T) * sym_count)) {
   469         if (target == MASTER) {
   470             printf(
"ERROR (T1): Master RX buffer invalid. \r\n ");
   472             printf(
"ERROR (T1): Slave RX buffer invalid. \r\n ");
   477     if (!check_buffers(tx_pattern, p_tx_buff, 
sizeof(T) * sym_count)) {
   478         if (target == MASTER) {
   479             printf(
"ERROR (T1): Master TX buffer invalid. \r\n ");
   481             printf(
"ERROR (T1): Slave TX buffer invalid. \r\n ");
   486     if (clocked_symbols_1 != count) {
   487         if (target == MASTER) {
   488             printf(
"ERROR (T1): Master Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_1, count);
   490             printf(
"ERROR (T1): Slave Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_1,
   497         dump_buffers<T>(target, tx_pattern, rx1_pattern, rx2_pattern, tx_buff, rx_buff);
   502     if (p_tx_buff && p_rx_buff) {
   503         memcpy(p_tx_buff, p_rx_buff, 
sizeof(T) * sym_count);
   504         memcpy(tx_pattern, p_rx_buff, 
sizeof(T) * sym_count);
   507     set_buffer(rx_buff, 
sizeof(T) * sym_count, 0x00);
   510     wait_before_transmission(target);
   512     if (target == MASTER) {
   516     count = sync_async_transfer(obj, p_tx_buff, sym_count, p_rx_buff, sym_count, (
void *) &fill_symbol, sync);
   518     if (target == MASTER) {
   519         handle_ss(ss, 
false);
   522     if (!check_buffers(rx2_pattern, p_rx_buff, 
sizeof(T) * sym_count)) {
   523         if (target == MASTER) {
   524             printf(
"ERROR (T2): Master RX buffer invalid. \r\n ");
   526             printf(
"ERROR (T2): Slave RX buffer invalid. \r\n ");
   532     if (!check_buffers(tx_pattern, p_tx_buff, 
sizeof(T) * sym_count)) {
   533         if (target == MASTER) {
   534             printf(
"ERROR (T2): Master TX buffer invalid. \r\n ");
   536             printf(
"ERROR (T2): Slave TX buffer invalid. \r\n ");
   541     if (clocked_symbols_2 != count) {
   542         if (target == MASTER) {
   543             printf(
"ERROR (T2): Master Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_2, count);
   545             printf(
"ERROR (T2): Slave Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_2,
   552         dump_buffers<T>(target, tx_pattern, rx1_pattern, rx2_pattern, tx_buff, rx_buff);
   568 void transfer_thread(
void *thread_params)
   573     if (params->config->symbol_size <= 8) {
   574         status = perform_transfer<uint8_t>(params->target, params->obj, params->config, params->ss);
   575     } 
else if (params->config->symbol_size <= 16) {
   576         status = perform_transfer<uint16_t>(params->target, params->obj, params->config, params->ss);
   578         status = perform_transfer<uint32_t>(params->target, params->obj, params->config, params->ss);
   581     transfer_finished = 
true;
   583     params->status = status;
   585     transm_sem.release();
 
bool hw_cs_handle
If true, in SPI master mode Chip Select can be handled by hardware. 
bool support_slave_mode
If true, the device can handle SPI slave mode using hardware management on the specified ssel pin...
uint32_t minimum_frequency
Minimum frequency supported must be set by target device and it will be assessed during testing...
Event data reported to interrupt's callback. 
uint32_t maximum_frequency
Maximum frequency supported must be set by target device and it will be assessed during testing...
uint8_t clk_modes
specifies supported modes from spi_mode_t. 
uint8_t bit_order
specifies supported bit order from spi_bit_ordering_t. 
SPIName spi_get_module(PinName mosi, PinName miso, PinName mclk)
Returns a variant of the SPIName enum uniquely identifying a SPI peripheral of the device...
void spi_get_capabilities(SPIName name, PinName ssel, bool slave, spi_capabilities_t *cap)
Fills the given spi_capabilities_t structure with the capabilities of the given peripheral. 
Describes the capabilities of a SPI peripherals. 
bool async_mode
If true, in async mode is supported. 
enum _spi_mode_t spi_mode_t
SPI modes. 
enum _spi_bit_ordering_t spi_bit_ordering_t
SPI bit ordering. 
bool spi_transfer_async(spi_t *obj, const void *tx, uint32_t tx_len, void *rx, uint32_t rx_len, const void *fill_symbol, spi_async_handler_f handler, void *ctx, DMAUsage hint)
Transfer data returning immediately. 
#define CMDLINE_RETCODE_SUCCESS
Execution Success. 
uint32_t spi_transfer(spi_t *obj, const void *tx, uint32_t tx_len, void *rx, uint32_t rx_len, const void *fill_symbol)
Transfer data blocking until the end of the operation. 
bool half_duplex
If true, the device also supports SPI transmissions using only 3 wires. 
uint32_t word_length
Each bit represents the corresponding word length.