Mistake on this page?
Report an issue in GitHub or email us
spi_master.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 /* Function initialises RX, TX buffers before transmission. */
18 template<typename T>
19 void init_transmission_buffers_master(config_test_case_t *config, T *p_tx_pattern, T *p_rx1_pattern, T *p_rx2_pattern,
20  T *p_tx_buff, T *p_rx_buff, T *p_fill_symbol)
21 {
22  uint8_t tx_pattern[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };
23  uint8_t rx_pattern[] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
24 
25  /* Default patterns for TX/RX buffers. */
26  init_buffer_with_pattern(p_tx_pattern, sym_count, sizeof(T), tx_pattern, sizeof(tx_pattern));
27  init_buffer_with_pattern(p_rx1_pattern, sym_count, sizeof(T), rx_pattern, sizeof(rx_pattern));
28  init_buffer_with_pattern(p_rx2_pattern, sym_count, sizeof(T), tx_pattern, sizeof(tx_pattern));
29 
30  set_buffer(p_fill_symbol, sizeof(T), 0xF5);
31 
32  /* Exception: master TX > master RX . */
33  if (config->master_tx_cnt > config->master_rx_cnt) {
34  set_buffer(&p_rx1_pattern[3], sizeof(T), 0x00);
35  set_buffer(&p_rx1_pattern[4], sizeof(T), 0x00);
36  }
37  /* Exception: master TX < master RX . */
38  if (config->master_tx_cnt < config->master_rx_cnt) {
39  set_buffer(&p_rx2_pattern[3], sizeof(T), 0xF5);
40  set_buffer(&p_rx2_pattern[4], sizeof(T), 0xF5);
41  }
42 
43  /* Exception: slave TX > slave RX . */
44  if (config->slave_tx_cnt > config->slave_rx_cnt) {
45  set_buffer(&p_rx2_pattern[3], sizeof(T), 0x00);
46  set_buffer(&p_rx2_pattern[4], sizeof(T), 0x00);
47  }
48  /* Exception: slave TX < slave RX . */
49  if (config->slave_tx_cnt < config->slave_rx_cnt) {
50  set_buffer(&p_rx1_pattern[3], sizeof(T), 0xF5);
51  set_buffer(&p_rx1_pattern[4], sizeof(T), 0xF5);
52  }
53 
54  /* Exception: master TX buffer undefined . */
55  if (!config->master_tx_defined) {
56  set_buffer(&p_rx2_pattern[0], sizeof(T), 0xF5);
57  set_buffer(&p_rx2_pattern[1], sizeof(T), 0xF5);
58  set_buffer(&p_rx2_pattern[2], sizeof(T), 0xF5);
59  set_buffer(&p_rx2_pattern[3], sizeof(T), 0xF5);
60  set_buffer(&p_rx2_pattern[4], sizeof(T), 0xF5);
61  }
62 
63  /* Exception: master RX buffer undefined . */
64  if (!config->master_rx_defined) {
65  set_buffer(&p_rx1_pattern[0], sizeof(T), 0xAA);
66  set_buffer(&p_rx1_pattern[1], sizeof(T), 0xBB);
67  set_buffer(&p_rx1_pattern[2], sizeof(T), 0xCC);
68  set_buffer(&p_rx1_pattern[3], sizeof(T), 0xDD);
69  set_buffer(&p_rx1_pattern[4], sizeof(T), 0xEE);
70  }
71 
72  /* Exception: slave TX buffer undefined . */
73  if (!config->slave_tx_defined) {
74  set_buffer(&p_rx1_pattern[0], sizeof(T), 0xF5);
75  set_buffer(&p_rx1_pattern[1], sizeof(T), 0xF5);
76  set_buffer(&p_rx1_pattern[2], sizeof(T), 0xF5);
77  set_buffer(&p_rx1_pattern[3], sizeof(T), 0xF5);
78  set_buffer(&p_rx1_pattern[4], sizeof(T), 0xF5);
79 
80  set_buffer(&p_rx2_pattern[0], sizeof(T), 0xF5);
81  set_buffer(&p_rx2_pattern[1], sizeof(T), 0xF5);
82  set_buffer(&p_rx2_pattern[2], sizeof(T), 0xF5);
83  set_buffer(&p_rx2_pattern[3], sizeof(T), 0xF5);
84  set_buffer(&p_rx2_pattern[4], sizeof(T), 0xF5);
85  }
86 
87  /* Exception: slave RX buffer undefined . */
88  if (!config->slave_rx_defined) {
89  set_buffer(&p_rx2_pattern[0], sizeof(T), 0x11);
90  set_buffer(&p_rx2_pattern[1], sizeof(T), 0x22);
91  set_buffer(&p_rx2_pattern[2], sizeof(T), 0x33);
92  set_buffer(&p_rx2_pattern[3], sizeof(T), 0x44);
93  set_buffer(&p_rx2_pattern[4], sizeof(T), 0x55);
94  }
95 
96  /* Handle symbol size. */
97  T sym_mask = ((1 << config->symbol_size) - 1);
98 
99  for (uint32_t i = 0; i < sym_count; i++) {
100  p_tx_pattern[i] = (p_tx_pattern[i] & sym_mask);
101  p_rx1_pattern[i] = (p_rx1_pattern[i] & sym_mask);
102  p_rx2_pattern[i] = (p_rx2_pattern[i] & sym_mask);
103  }
104 
105  memcpy(p_tx_buff, p_tx_pattern, sizeof(T) * sym_count);
106  set_buffer(p_rx_buff, sizeof(T) * sym_count, 0x00);
107 }
108 
109 /* Function handles test_init command. */
110 int test_init_master(spi_t *obj, config_test_case_t *config, DigitalOut **ss)
111 {
112  spi_capabilities_t capabilities_master = { 0 };
113  spi_capabilities_t capabilities_slave = { 0 };
114  PinName ss_pin = MASTER_SPI_SS;
115  PinName miso = MASTER_SPI_MISO;
116  PinName mosi = MASTER_SPI_MOSI;
117 
118  spi_get_capabilities(spi_get_module(MASTER_SPI_MOSI, MASTER_SPI_MISO, MASTER_SPI_CLK), MASTER_SPI_SS, false, &capabilities_master);
119 
120  spi_get_capabilities(spi_get_module(SLAVE_SPI_MOSI, SLAVE_SPI_MISO, SLAVE_SPI_CLK), SLAVE_SPI_SS, true, &capabilities_slave);
121 
122  /* Adapt Half Duplex settings. */
123  if (config->duplex == HALF_DUPLEX) {
124  if (MASTER_SPI_HF_DATA == MASTER_SPI_MOSI) {
125  miso = NC;
126  } else if (MASTER_SPI_HF_DATA == MASTER_SPI_MISO) {
127  mosi = NC;
128  } else {
129  printf("ERROR: Master init in half duplex mode. \r\n ");
130  }
131  }
132 
133  /* Adapt min/max frequency for testing based of capabilities. */
134  switch (config->freq_hz) {
135  case FREQ_MIN:
136  config->freq_hz = (capabilities_master.minimum_frequency < capabilities_slave.minimum_frequency ? capabilities_slave.minimum_frequency : capabilities_master.minimum_frequency);
137  break;
138 
139  case FREQ_MAX:
140  config->freq_hz = (capabilities_master.maximum_frequency > capabilities_slave.maximum_frequency ? capabilities_slave.maximum_frequency : capabilities_master.maximum_frequency);
141  break;
142 
143  default:
144  break;
145  }
146 
147  /* Adapt manual/auto SS handling by master. */
148  if (!config->auto_ss) {
149  ss_pin = NC;
150  *ss = new DigitalOut(MASTER_SPI_SS);
151  **ss = SS_DEASSERT;
152  }
153 
154  spi_init(obj, false, mosi, miso, MASTER_SPI_CLK, ss_pin);
155 
156  spi_format(obj, config->symbol_size, config->mode, config->bit_ordering);
157 
158  spi_frequency(obj, config->freq_hz);
159 
161 }
162 
163 /* Function handles test_transfer command. */
164 int test_transfer_master(spi_t *obj, config_test_case_t *config, DigitalOut *ss)
165 {
166  Timeout transm_thread_timeout;
167  Thread transm_thread(osPriorityNormal);
168 
169  int status = CMDLINE_RETCODE_SUCCESS;
170  trans_thread_params_t trans_thread_params = { obj, MASTER, config, ss, CMDLINE_RETCODE_SUCCESS };
171 
172  /* Set slave transmission test timeout to 5 sec + master delays */
173  transm_thread_timeout.attach_us(transm_timeout_handler, 5 * US_PER_S + 2 * MASTER_TRANSMISSION_DELAY_MS * US_PER_MS);
174 
175  transfer_finished = false;
176 
177  transm_thread.start(callback(transfer_thread, (void *) &trans_thread_params));
178 
179  transm_sem.wait();
180 
181  if (!transfer_finished) {
182  transm_thread.terminate();
183  printf("ERROR: Master transmission timeout. \r\n ");
184  }
185  return status;
186 }
187 
188 /* Function handles test_finish command. */
189 int test_finish_master(spi_t *obj, config_test_case_t *config)
190 {
191  spi_free(obj);
192 
194 }
195 
void spi_init(spi_t *obj, bool is_slave, PinName mosi, PinName miso, PinName mclk, PinName ssel)
Initialized a spi peripheral.
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
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
Callback< R()> callback(R(*func)()=0)
Create a callback class with type inferred from the arguments.
Definition: Callback.h:3848
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
uint32_t spi_frequency(spi_t *obj, uint32_t hz)
Set the frequency target.
void spi_format(spi_t *obj, uint8_t bits, spi_mode_t mode, spi_bit_ordering_t bit_ordering)
Configure the format to be used by the SPI peripheral.
#define CMDLINE_RETCODE_SUCCESS
Execution Success.
Definition: ns_cmdline.h:72
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.