1 /***************************************************************************//**
2 * \file cy_scb_common.c
3 * \version 3.10
4 *
5 * Provides common API implementation of the SCB driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2016-2021 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25 #include "cy_device.h"
26
27 #if (defined (CY_IP_MXSCB) || defined (CY_IP_MXS22SCB))
28
29 #include "cy_scb_common.h"
30
31 #if defined(__cplusplus)
32 extern "C" {
33 #endif
34
35 /*******************************************************************************
36 * Function Name: Cy_SCB_ReadArrayNoCheck
37 ****************************************************************************//**
38 *
39 * Reads an array of data out of the SCB receive FIFO without checking if the
40 * receive FIFO has enough data elements.
41 * Before calling this function, make sure that the receive FIFO has enough data
42 * elements to be read.
43 *
44 * \param base
45 * The pointer to the SCB instance.
46 *
47 * \param buffer
48 * The pointer to location to place data read from the receive FIFO.
49 * The size of the data element defined by the configured data width.
50 *
51 * \param size
52 * The number of data elements read from the receive FIFO.
53 *
54 *******************************************************************************/
Cy_SCB_ReadArrayNoCheck(CySCB_Type const * base,void * buffer,uint32_t size)55 void Cy_SCB_ReadArrayNoCheck(CySCB_Type const *base, void *buffer, uint32_t size)
56 {
57 uint32_t idx;
58 #if((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
59 if (Cy_SCB_IsRxDataWidthByte(base))
60 {
61 uint8_t *buf = (uint8_t *) buffer;
62
63 /* Get data available in RX FIFO */
64 for (idx = 0UL; idx < size; ++idx)
65 {
66 buf[idx] = (uint8_t) Cy_SCB_ReadRxFifo(base);
67 }
68 }
69 else
70 {
71 uint16_t *buf = (uint16_t *) buffer;
72
73 /* Get data available in RX FIFO */
74 for (idx = 0UL; idx < size; ++idx)
75 {
76 buf[idx] = (uint16_t) Cy_SCB_ReadRxFifo(base);
77 }
78 }
79 #elif((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
80 uint32_t datawidth = Cy_SCB_Get_RxDataWidth(base);
81
82 if (datawidth <= CY_SCB_BYTE_WIDTH)
83 {
84 uint8_t *buf = (uint8_t *) buffer;
85
86 /* Get data available in RX FIFO */
87 for (idx = 0UL; idx < size; ++idx)
88 {
89 buf[idx] = (uint8_t) Cy_SCB_ReadRxFifo(base);
90 }
91 }
92 else if(datawidth <= CY_SCB_HALF_WORD_WIDTH)
93 {
94 uint16_t *buf = (uint16_t *) buffer;
95
96 /* Get data available in RX FIFO */
97 for (idx = 0UL; idx < size; ++idx)
98 {
99 buf[idx] = (uint16_t) Cy_SCB_ReadRxFifo(base);
100 }
101 }
102 else
103 {
104 uint32_t *buf = (uint32_t *) buffer;
105
106 /* Get data available in RX FIFO */
107 for (idx = 0UL; idx < size; ++idx)
108 {
109 buf[idx] = (uint32_t) Cy_SCB_ReadRxFifo(base);
110 }
111 }
112 #endif /* CY_IP_MXSCB_VERSION */
113 }
114
115
116 /*******************************************************************************
117 * Function Name: Cy_SCB_ReadArray
118 ****************************************************************************//**
119 *
120 * Reads an array of data out of the SCB receive FIFO.
121 * This function does not block; it returns how many data elements are
122 * read from the receive FIFO.
123 *
124 * \param base
125 * The pointer to the SCB instance.
126 *
127 * \param buffer
128 * The pointer to location to place data read from receive FIFO.
129 * The item size is defined by the data type, which depends on the configured
130 * data width.
131 *
132 * \param size
133 * The number of data elements to read from the receive FIFO.
134 *
135 * \return
136 * The number of data elements read from the receive FIFO.
137 *
138 *******************************************************************************/
Cy_SCB_ReadArray(CySCB_Type const * base,void * buffer,uint32_t size)139 uint32_t Cy_SCB_ReadArray(CySCB_Type const *base, void *buffer, uint32_t size)
140 {
141 /* Get available items in RX FIFO */
142 uint32_t numToCopy = Cy_SCB_GetNumInRxFifo(base);
143
144 /* Adjust items that will be read */
145 if (numToCopy > size)
146 {
147 numToCopy = size;
148 }
149
150 /* Get data available in RX FIFO */
151 Cy_SCB_ReadArrayNoCheck(base, buffer, numToCopy);
152
153 return (numToCopy);
154 }
155
156
157 /*******************************************************************************
158 * Function Name: Cy_SCB_ReadArrayBlocking
159 ****************************************************************************//**
160 *
161 * Reads an array of data out of the SCB receive FIFO.
162 * This function blocks until the number of data elements specified by the
163 * size has been read from the receive FIFO.
164 *
165 * \param base
166 * The pointer to the SCB instance.
167 *
168 * \param buffer
169 * The pointer to the location to place data read from the receive FIFO.
170 * The item size is defined by the data type, which depends on the configured
171 * data width.
172 *
173 * \param size
174 * The number of data elements to read from receive FIFO.
175 *
176 *******************************************************************************/
Cy_SCB_ReadArrayBlocking(CySCB_Type const * base,void * buffer,uint32_t size)177 void Cy_SCB_ReadArrayBlocking(CySCB_Type const *base, void *buffer, uint32_t size)
178 {
179 uint32_t numCopied;
180 uint8_t *buf = (uint8_t *) buffer;
181 #if((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
182 uint32_t datawidth = Cy_SCB_Get_RxDataWidth(base);
183 #elif((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
184 bool byteMode = Cy_SCB_IsRxDataWidthByte(base);
185 #endif /* CY_IP_MXSCB_VERSION */
186 /* Get data from RX FIFO. Stop when the requested size is read. */
187 while (size > 0UL)
188 {
189 numCopied = Cy_SCB_ReadArray(base, (void *) buf, size);
190 #if((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
191 buf = &buf[((datawidth/8UL) * numCopied)];
192 #elif((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
193 buf = &buf[(byteMode ? (numCopied) : (2UL * numCopied))];
194 #endif /* CY_IP_MXSCB_VERSION */
195 size -= numCopied;
196 }
197 }
198
199
200 /*******************************************************************************
201 * Function Name: Cy_SCB_Write
202 ****************************************************************************//**
203 *
204 * Places a single data element in the SCB transmit FIFO.
205 * This function does not block. It returns how many data elements are placed
206 * in the transmit FIFO.
207 *
208 * \param base
209 * The pointer to the SCB instance.
210 *
211 * \param data
212 * Data to put in the transmit FIFO.
213 * The item size is defined by the data type, which depends on the configured
214 * data width.
215 *
216 * \return
217 * The number of data elements placed in the transmit FIFO: 0 or 1.
218 *
219 *******************************************************************************/
Cy_SCB_Write(CySCB_Type * base,uint32_t data)220 uint32_t Cy_SCB_Write(CySCB_Type *base, uint32_t data)
221 {
222 uint32_t numCopied = 0UL;
223
224 if (Cy_SCB_GetFifoSize(base) != Cy_SCB_GetNumInTxFifo(base))
225 {
226 Cy_SCB_WriteTxFifo(base, data);
227
228 numCopied = 1UL;
229 }
230
231 return (numCopied);
232 }
233
234
235 /*******************************************************************************
236 * Function Name: Cy_SCB_WriteArrayNoCheck
237 ****************************************************************************//**
238 *
239 * Places an array of data in the SCB transmit FIFO without checking whether the
240 * transmit FIFO has enough space.
241 * Before calling this function, make sure that the transmit FIFO has enough
242 * space to put all requested data elements.
243 *
244 * \param base
245 * The pointer to the SCB instance.
246 *
247 * \param buffer
248 * The pointer to data to place in the transmit FIFO.
249 * The item size is defined by the data type, which depends on the configured
250 * TX data width.
251 *
252 * \param size
253 * The number of data elements to transmit.
254 *
255 * \return
256 * The number of data elements placed in the transmit FIFO.
257 *
258 *******************************************************************************/
Cy_SCB_WriteArrayNoCheck(CySCB_Type * base,void * buffer,uint32_t size)259 void Cy_SCB_WriteArrayNoCheck(CySCB_Type *base, void *buffer, uint32_t size)
260 {
261 uint32_t idx;
262 #if((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
263 if (Cy_SCB_IsTxDataWidthByte(base))
264 {
265 uint8_t *buf = (uint8_t *) buffer;
266
267 /* Put data into TX FIFO */
268 for (idx = 0UL; idx < size; ++idx)
269 {
270 Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
271 }
272 }
273 else
274 {
275 uint16_t *buf = (uint16_t *) buffer;
276
277 /* Put data into TX FIFO */
278 for (idx = 0UL; idx < size; ++idx)
279 {
280 Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
281 }
282 }
283 #elif((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
284 uint32_t datawidth = Cy_SCB_Get_TxDataWidth(base);
285
286 if (datawidth <= CY_SCB_BYTE_WIDTH)
287 {
288 uint8_t *buf = (uint8_t *) buffer;
289
290 /* Put data into TX FIFO */
291 for (idx = 0UL; idx < size; ++idx)
292 {
293 Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
294 }
295 }
296 else if(datawidth <= CY_SCB_HALF_WORD_WIDTH)
297 {
298 uint16_t *buf = (uint16_t *) buffer;
299
300 /* Put data into TX FIFO */
301 for (idx = 0UL; idx < size; ++idx)
302 {
303 Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
304 }
305 }
306 else
307 {
308 uint32_t *buf = (uint32_t *) buffer;
309
310 /* Put data into TX FIFO */
311 for (idx = 0UL; idx < size; ++idx)
312 {
313 Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
314 }
315 }
316 #endif /* CY_IP_MXSCB_VERSION */
317 }
318
319
320 /*******************************************************************************
321 * Function Name: Cy_SCB_WriteArray
322 ****************************************************************************//**
323 *
324 * Places an array of data in the SCB transmit FIFO.
325 * This function does not block. It returns how many data elements were
326 * placed in the transmit FIFO.
327 *
328 * \param base
329 * The pointer to the SCB instance.
330 *
331 * \param buffer
332 * The pointer to data to place in the transmit FIFO.
333 * The item size is defined by the data type which depends on the configured
334 * TX data width.
335 *
336 * \param size
337 * The number of data elements to transmit.
338 *
339 * \return
340 * The number of data elements placed in the transmit FIFO.
341 *
342 *******************************************************************************/
Cy_SCB_WriteArray(CySCB_Type * base,void * buffer,uint32_t size)343 uint32_t Cy_SCB_WriteArray(CySCB_Type *base, void *buffer, uint32_t size)
344 {
345 /* Get free entries in TX FIFO */
346 uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
347
348 /* Adjust the data elements to write */
349 if (numToCopy > size)
350 {
351 numToCopy = size;
352 }
353
354 Cy_SCB_WriteArrayNoCheck(base, buffer, numToCopy);
355
356 return (numToCopy);
357 }
358
359
360 /*******************************************************************************
361 * Function Name: Cy_SCB_WriteArrayBlocking
362 ****************************************************************************//**
363 *
364 * Places an array of data in the transmit FIFO.
365 * This function blocks until the number of data elements specified by the size
366 * is placed in the transmit FIFO.
367 *
368 * \param base
369 * The pointer to the SCB instance.
370 *
371 * \param buffer
372 * The pointer to data to place in transmit FIFO.
373 * The item size is defined by the data type, which depends on the configured
374 * data width.
375 *
376 * \param size
377 * The number of data elements to write into the transmit FIFO.
378 *
379 *******************************************************************************/
Cy_SCB_WriteArrayBlocking(CySCB_Type * base,void * buffer,uint32_t size)380 void Cy_SCB_WriteArrayBlocking(CySCB_Type *base, void *buffer, uint32_t size)
381 {
382 uint32_t numCopied;
383 uint8_t *buf = (uint8_t *) buffer;
384 #if((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
385 uint32_t datawidth = Cy_SCB_Get_TxDataWidth(base);
386 #elif((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
387 bool byteMode = Cy_SCB_IsTxDataWidthByte(base);
388 #endif /* CY_IP_MXSCB_VERSION */
389 /* Get data from RX FIFO. Stop when the requested size is read. */
390 while (size > 0UL)
391 {
392 numCopied = Cy_SCB_WriteArray(base, (void *) buf, size);
393 #if((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB))
394 buf = &buf[((datawidth/8UL) * numCopied)];
395 #elif((defined (CY_IP_MXSCB_VERSION) && CY_IP_MXSCB_VERSION==1))
396 buf = &buf[(byteMode ? (numCopied) : (2UL * numCopied))];
397 #endif /* CY_IP_MXSCB_VERSION */
398 size -= numCopied;
399 }
400 }
401
402
403 /*******************************************************************************
404 * Function Name: Cy_SCB_WriteString
405 ****************************************************************************//**
406 *
407 * Places a NULL terminated string in the transmit FIFO.
408 * This function blocks until the entire string is placed in the transmit FIFO.
409 *
410 * \param base
411 * The pointer to the SCB instance.
412 *
413 * \param string
414 * The pointer to the null terminated string array.
415 *
416 *******************************************************************************/
Cy_SCB_WriteString(CySCB_Type * base,char_t const string[])417 void Cy_SCB_WriteString(CySCB_Type *base, char_t const string[])
418 {
419 uint32_t idx = 0UL;
420 uint32_t fifoSize = Cy_SCB_GetFifoSize(base);
421
422 /* Put data from TX FIFO. Stop when string is terminated */
423 while (((char_t) 0) != string[idx])
424 {
425 /* Wait for free space to be available */
426 while (fifoSize == Cy_SCB_GetNumInTxFifo(base))
427 {
428 }
429
430 Cy_SCB_WriteTxFifo(base, (uint32_t) string[idx]);
431 ++idx;
432 }
433 }
434
435
436 /*******************************************************************************
437 * Function Name: Cy_SCB_WriteDefaultArrayNoCheck
438 ****************************************************************************//**
439 *
440 * Places a number of the same data elements in the SCB transmit FIFO without
441 * checking whether the transmit FIFO has enough space. The data elements is equal
442 * to txData parameter.
443 * Before calling this function, make sure that transmit FIFO has enough space
444 * to put all requested data elements.
445 *
446 * \param base
447 * The pointer to the SCB instance.
448 *
449 * \param txData
450 * The data element to transmit repeatedly.
451 *
452 * \param size
453 * The number of data elements to transmit.
454 *
455 *******************************************************************************/
Cy_SCB_WriteDefaultArrayNoCheck(CySCB_Type * base,uint32_t txData,uint32_t size)456 void Cy_SCB_WriteDefaultArrayNoCheck(CySCB_Type *base, uint32_t txData, uint32_t size)
457 {
458 while (size > 0UL)
459 {
460 Cy_SCB_WriteTxFifo(base, txData);
461 --size;
462 }
463 }
464
465
466 /*******************************************************************************
467 * Function Name: Cy_SCB_WriteDefaultArray
468 ****************************************************************************//**
469 *
470 * Places a number of the same data elements in the SCB transmit FIFO.
471 * The data elements is equal to the txData parameter.
472 *
473 * \param base
474 * The pointer to the SCB instance.
475 *
476 * \param txData
477 * The data element to transmit repeatedly.
478 *
479 * \param size
480 * The number of data elements to transmit.
481 *
482 * \return
483 * The number of data elements placed in the transmit FIFO.
484 *
485 *******************************************************************************/
Cy_SCB_WriteDefaultArray(CySCB_Type * base,uint32_t txData,uint32_t size)486 uint32_t Cy_SCB_WriteDefaultArray(CySCB_Type *base, uint32_t txData, uint32_t size)
487 {
488 /* Get free entries in TX FIFO */
489 uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
490
491 /* Adjust data elements to write */
492 if (numToCopy > size)
493 {
494 numToCopy = size;
495 }
496
497 Cy_SCB_WriteDefaultArrayNoCheck(base, txData, numToCopy);
498
499 return (numToCopy);
500 }
501
502 #if defined(__cplusplus)
503 }
504 #endif
505
506 #endif /* (defined (CY_IP_MXSCB) || defined (CY_IP_MXS22SCB)) */
507
508 /* [] END OF FILE */
509