Mistake on this page?
Report an issue in GitHub or email us
spi_test_common.h
1 /*
2  * Copyright (c) 2018 ARM Limited. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  * Licensed under the Apache License, Version 2.0 (the License); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
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!
31 #endif
32 
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
37 
38 #define FREQ_200KHZ (200000)
39 #define FREQ_1MHZ (1000000)
40 #define FREQ_2MHZ (2000000)
41 #define FREQ_MIN (0)
42 #define FREQ_MAX (-1)
43 #define US_PER_MS (1000)
44 #define US_PER_S (1000000)
45 
46 #define MASTER_SYNC_BIT_MASK 1
47 #define SLAVE_SYNC_BIT_MASK 2
48 
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
56 
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
64 
65 #define TEST_CAPABILITY_BIT(MASK, CAP) ((1 << CAP) & (MASK))
66 
67 #define DEBUG MBED_CONF_APP_SPI_DEBUG
68 
69 #if(MASTER_SPI_SS_ACTIVE_HIGH)
70 #define SS_ASSERT 1
71 #define SS_DEASSERT 0
72 #else
73 #define SS_ASSERT 0
74 #define SS_DEASSERT 1
75 #endif
76 
77 /* Duplex modes for testing. */
78 typedef enum {
79  FULL_DUPLEX,
80  HALF_DUPLEX
81 } duplex_t;
82 
83 /* Target definition. */
84 typedef enum {
85  MASTER,
86  SLAVE
87 } target_t;
88 
89 /* Buffer cases for testing. */
90 typedef enum {
91  SPI_BUFFERS_EQUAL,
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,
96  SPI_BUFFERS_SHORTEST,
97  SPI_BUFFERS_LONG
98 } buffers_t;
99 
100 /* SPI test configuration. */
101 typedef struct {
102  uint8_t symbol_size;
103  spi_mode_t mode;
104  spi_bit_ordering_t bit_ordering;
105  uint32_t freq_hz;
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;
114  bool auto_ss;
115  duplex_t duplex;
116  bool master_sync;
117  bool slave_sync;
119 
120 /* Transmission thread parameters. */
121 typedef struct {
122  spi_t *obj;
123  target_t target;
124  config_test_case_t *config;
125  DigitalOut *ss;
126  int status;
128 
129 template<typename T>
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);
132 
133 template<typename T>
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);
136 
137 /* Total number of transmitted symbols - provided by the configuration. */
138 static uint32_t sym_count = 0;
139 
140 /* Flag which indicates if spi transfer test has been finished. */
141 static volatile bool transfer_finished;
142 
143 /* Semaphore used to delay main task and execute transfer thread. */
144 static Semaphore transm_sem(0, 1);
145 
146 /* Timeout handler for the transfer thread. */
147 static void transm_timeout_handler()
148 {
149  transm_sem.release();
150 }
151 
152 /* Function inserts symbol string into the message. */
153 static void msg_insert_symbol(uint8_t *buffer, uint8_t *symbol_str)
154 {
155  sprintf((char *) buffer, " %s", (char *) symbol_str);
156 }
157 
158 /* Function builds message based on array with symbols. */
159 template<typename T>
160 static void mgs_init(uint8_t *buffer, T *symbols, const char *dut, const char *buf_name)
161 {
162  uint8_t *p_buffer = buffer;
163  uint8_t symbol[32];
164 
165  sprintf((char *) buffer, "%s %s", dut, buf_name);
166  p_buffer += strlen((const char *) buffer);
167 
168  for (uint32_t i = 0; i < sym_count; i++) {
169  sprintf((char *) symbol, "0x%X", symbols[i]);
170 
171  msg_insert_symbol(p_buffer, symbol);
172  p_buffer += (strlen((const char *) symbol) + 1);
173  }
174 
175  sprintf((char *) p_buffer, "%s", "\r\n");
176 }
177 
178 /* Debug function to dump tx/rx buffers. */
179 template<typename T>
180 static void dump_buffers(target_t target, T *tx_pattern, T *rx1_pattern, T *rx2_pattern, T *tx_buff, T *rx_buff)
181 {
182 #if DEBUG
183  uint8_t buffer[1024];
184  uint8_t dut[8];
185 
186  if (target == MASTER) {
187  /* Wait a while so the messages from master and slave are not mixed. */
188  wait_ms(100);
189  strcpy((char *)dut, "master");
190  } else {
191  strcpy((char *)dut, "slave");
192  }
193 
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);
203 #endif
204 }
205 
206 /* Debug function to print configuration details. */
207 void dump_config(config_test_case_t *config)
208 {
209 #if DEBUG
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);
227 #endif
228 }
229 
230 /* Function inits specified buffer with given pattern. */
231 static void set_buffer(void *addr, uint32_t size, uint8_t val)
232 {
233  char *p_char = (char *) addr;
234 
235  for (uint32_t i = 0; i < size; i++) {
236  p_char[i] = val;
237  }
238 }
239 
240 /* Function inits array of symbols with given pattern.
241  *
242  * Example:
243  * 12 bytes buffer filled with 16 bit (2 bytes) symbols and pattern 0xAA 0xBB 0xCC
244  * will be build as follows:
245  * 0xAAAA 0cBBBB 0xCCCC 0xAAAA 0xBBBB 0xCCCC
246  *
247  */
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)
250 {
251  uint32_t pattern_idx = 0;
252 
253  while (sym_count) {
254  set_buffer(p_buffer, sym_size, p_pattern[pattern_idx]);
255 
256  p_buffer += sym_size;
257 
258  pattern_idx++;
259  if (pattern_idx == pattern_sym_count) {
260  pattern_idx = 0;
261  }
262 
263  sym_count--;
264  }
265 }
266 
267 /* Function handles ss line if ss is specified. */
268 static void handle_ss(DigitalOut *ss, bool select)
269 {
270  if (ss) {
271  if (select) {
272  *ss = SS_ASSERT;
273  } else {
274  *ss = SS_DEASSERT;
275  }
276  }
277 }
278 
279 #ifdef DEVICE_SPI_ASYNCH
280 /* Callback function for SPI async transfers. */
281 static uint32_t context;
282 static volatile bool async_transm_done;
283 static volatile uint32_t async_transfered;
284 void spi_async_callback(spi_t *obj, void *ctx, spi_async_event_t *event)
285 {
286  async_transm_done = true;
287  async_transfered = event->transfered;
288 }
289 #endif
290 
291 /* Function returns true if configuration is consistent with the capabilities of
292  * the SPI peripheral, false otherwise. */
293 static int check_capabilities(config_test_case_t *tc_config, bool slave)
294 {
295  spi_capabilities_t capabilities = { 0 };
296  if (slave) {
297  spi_get_capabilities(spi_get_module(MASTER_SPI_MOSI, MASTER_SPI_MISO, MASTER_SPI_CLK), MASTER_SPI_SS, true, &capabilities);
298  } else {
299  spi_get_capabilities(spi_get_module(SLAVE_SPI_MOSI, SLAVE_SPI_MISO, SLAVE_SPI_CLK), SLAVE_SPI_SS, false, &capabilities);
300  }
301 
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)) ||
305  (slave && !capabilities.support_slave_mode) ||
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)
311  ) {
312  if (!slave) {
313  printf("SKIP: Configuration not supported by master.\r\n");
314  } else {
315  printf("SKIP: Configuration not supported by slave.\r\n");
316  }
317  }
318 
320 }
321 
322 /* Function used to perform transmission using sync or async modes. */
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)
325 {
326  uint32_t count = 0;
327 
328  if (sync_mode) {
329  count = spi_transfer(obj, tx, tx_len, rx, rx_len, fill_symbol);
330  }
331 #ifdef DEVICE_SPI_ASYNCH
332  else {
333  async_transm_done = false;
334  async_transfered = 0;
335 
336  spi_transfer_async(obj, tx, tx_len, rx, rx_len, fill_symbol, spi_async_callback, &context, DMA_USAGE_NEVER);
337 
338  /* Wait here for the end of the transmission. */
339  while (!async_transm_done) {
340  }
341 
342  count = async_transfered;
343  }
344 #endif
345 
346  return count;
347 }
348 
349 /* Function waits before the transmission.
350  * It takes params from the app configuration. If TRANSMISSION_DELAY_MS is 0 and
351  * TRANSMISSION_BUTTON is specified then it is used to trigger the transmission
352  * (wait until button is pressed).
353  * TRANSMISSION_LED can be specified to indicate waiting. This features might be useful while
354  * driver development and debugging.
355  */
356 static void wait_before_transmission(target_t target)
357 {
358  if (target == MASTER) {
359  wait_ms(MASTER_TRANSMISSION_DELAY_MS);
360  } else {
361  wait_ms(SLAVE_TRANSMISSION_DELAY_MS);
362  }
363 }
364 
365 /* Function compares given buffers and returns true when equal, false otherwise.
366  * In case when buffer is undefined (NULL) function returns true.
367  */
368 static bool check_buffers(void *p_pattern, void *p_buffer, uint32_t size)
369 {
370  const char *p_byte_pattern = (const char *) p_pattern;
371  const char *p_byte_buffer = (const char *) p_buffer;
372 
373  if (p_buffer == NULL || p_pattern == NULL) {
374  return true;
375  }
376 
377  while (size) {
378  if (*p_byte_pattern != *p_byte_buffer) {
379  return false;
380  }
381  p_byte_pattern++;
382  p_byte_buffer++;
383  size--;
384  }
385 
386  return true;
387 }
388 
389 /* Function which perform transfer using specified config.
390  *
391  * Note:
392  * SS for slave is NULL.
393  * SS for master must is NULL when ss is handled automatically or defined in case of
394  * manual handling.
395  *
396  */
397 template<typename T>
398 static int perform_transfer(target_t target, spi_t *obj, config_test_case_t *config, DigitalOut *ss)
399 {
400  uint32_t count;
401  bool test_passed;
402  bool sync;
403  int status = CMDLINE_RETCODE_SUCCESS;
404 
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];
410  T fill_symbol;
411 
412  void *p_tx_buff = tx_buff;
413  void *p_rx_buff = rx_buff;
414 
415  uint32_t clocked_symbols_1 = sym_count;
416  uint32_t clocked_symbols_2 = sym_count;
417 
418  if (config->duplex != FULL_DUPLEX) {
419  if (target == MASTER) {
420  clocked_symbols_1 = (config->master_tx_cnt + config->master_rx_cnt);
421  } else {
422  clocked_symbols_1 = (config->slave_tx_cnt + config->slave_rx_cnt);
423  }
424 
425  clocked_symbols_2 = (sym_count + sym_count);
426  }
427 
428  if (target == MASTER) {
429  if (!config->master_tx_defined) {
430  p_tx_buff = NULL;
431  }
432 
433  if (!config->master_rx_defined) {
434  p_rx_buff = NULL;
435  }
436  sync = config->master_sync;
437  } else {
438  if (!config->slave_tx_defined) {
439  p_tx_buff = NULL;
440  }
441 
442  if (!config->slave_rx_defined) {
443  p_rx_buff = NULL;
444  }
445  sync = config->slave_sync;
446  }
447 
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],
450  &fill_symbol);
451  } else {
452  init_transmission_buffers_slave<T>(config, &tx_pattern[0], &rx1_pattern[0], &rx2_pattern[0], &tx_buff[0], &rx_buff[0],
453  &fill_symbol);
454  }
455 
456  test_passed = true;
457  wait_before_transmission(target);
458 
459  if (target == MASTER) {
460  handle_ss(ss, true);
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);
463  } else {
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);
466  }
467 
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 ");
471  } else {
472  printf("ERROR (T1): Slave RX buffer invalid. \r\n ");
473  }
474  test_passed = false;
475  }
476 
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 ");
480  } else {
481  printf("ERROR (T1): Slave TX buffer invalid. \r\n ");
482  }
483  test_passed = false;
484  }
485 
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);
489  } else {
490  printf("ERROR (T1): Slave Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_1,
491  count);
492  }
493  test_passed = false;
494  }
495 
496  if (!test_passed) {
497  dump_buffers<T>(target, tx_pattern, rx1_pattern, rx2_pattern, tx_buff, rx_buff);
498  }
499 
500  /* Init TX buffer with data received from slave if possible. */
501 
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);
505  }
506 
507  set_buffer(rx_buff, sizeof(T) * sym_count, 0x00);
508 
509  test_passed = true;
510  wait_before_transmission(target);
511 
512  if (target == MASTER) {
513  handle_ss(ss, true);
514  }
515 
516  count = sync_async_transfer(obj, p_tx_buff, sym_count, p_rx_buff, sym_count, (void *) &fill_symbol, sync);
517 
518  if (target == MASTER) {
519  handle_ss(ss, false);
520  }
521 
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 ");
525  } else {
526  printf("ERROR (T2): Slave RX buffer invalid. \r\n ");
527  }
528 
529  test_passed = false;
530  }
531 
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 ");
535  } else {
536  printf("ERROR (T2): Slave TX buffer invalid. \r\n ");
537  }
538  test_passed = false;
539  }
540 
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);
544  } else {
545  printf("ERROR (T2): Slave Clocked symbol count invalid (expected: %lu actual: %lu). \r\n ", clocked_symbols_2,
546  count);
547  }
548  test_passed = false;
549  }
550 
551  if (!test_passed) {
552  dump_buffers<T>(target, tx_pattern, rx1_pattern, rx2_pattern, tx_buff, rx_buff);
553  }
554 
555  delete tx_pattern;
556  delete rx1_pattern;
557  delete rx2_pattern;
558  delete tx_buff;
559  delete rx_buff;
560 
561  return status;
562 }
563 
564 /* Auxiliary thread which is used to handle transmission.
565  * In case when transmission is not finished after specified timeout, then
566  * this thread is terminated and test failure/timeout is indicated.
567  */
568 void transfer_thread(void *thread_params)
569 {
570  int status = CMDLINE_RETCODE_SUCCESS;
571  trans_thread_params_t *params = (trans_thread_params_t *) thread_params;
572 
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);
577  } else {
578  status = perform_transfer<uint32_t>(params->target, params->obj, params->config, params->ss);
579  }
580 
581  transfer_finished = true;
582 
583  params->status = status;
584 
585  transm_sem.release();
586 }
void wait_ms(int ms)
Waits a number of milliseconds.
bool hw_cs_handle
If true, in SPI master mode Chip Select can be handled by hardware.
Definition: spi_api.h:158
bool support_slave_mode
If true, the device can handle SPI slave mode using hardware management on the specified ssel pin...
Definition: spi_api.h:156
uint32_t minimum_frequency
Minimum frequency supported must be set by target device and it will be assessed during testing...
Definition: spi_api.h:146
Event data reported to interrupt&#39;s callback.
Definition: spi_api.h:184
uint32_t maximum_frequency
Maximum frequency supported must be set by target device and it will be assessed during testing...
Definition: spi_api.h:150
uint8_t clk_modes
specifies supported modes from spi_mode_t.
Definition: spi_api.h:154
uint8_t bit_order
specifies supported bit order from spi_bit_ordering_t.
Definition: spi_api.h:155
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.
Definition: spi_api.h:142
bool async_mode
If true, in async mode is supported.
Definition: spi_api.h:159
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.
Definition: ns_cmdline.h:72
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.
Definition: spi_api.h:157
uint32_t word_length
Each bit represents the corresponding word length.
Definition: spi_api.h:152
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.