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