[processor-sdk/pdk.git] / packages / ti / drv / mcbsp / example / c6657 / MCBSPDigLpbk / mcbspMasterDigLpbk_osal.c
1 /**
2 * @file mcbspMasterDigLpbk_osal.c
3 *
4 * @brief
5 * This is the OS abstraction layer and is used by the MCBSP
6 * driver for the MCBSP Example Digital Loopback Application.
7 *
8 * \par
9 * ============================================================================
10 * @n (C) Copyright 2012, Texas Instruments, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the
22 * distribution.
23 *
24 * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * \par
41 */
42 #include <xdc/std.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <xdc/runtime/IHeap.h>
47 #include <xdc/runtime/System.h>
48 #include <xdc/runtime/Memory.h>
49 #include <xdc/runtime/Error.h>
50 #include <ti/sysbios/knl/Semaphore.h>
51 #include <ti/sysbios/BIOS.h>
52 #include <ti/sysbios/knl/Task.h>
53 #include <ti/sysbios/knl/Queue.h>
54 #include <ti/sysbios/heaps/HeapBuf.h>
55 #include <ti/sysbios/heaps/HeapMem.h>
56 #include <ti/sysbios/hal/Hwi.h>
57 #include <xdc/cfg/global.h>
58 #include <ti/drv/mcbsp/mcbsp_drv.h>
59 #if 0
60 /* CSL Include Files */
61 #include <ti/csl/csl_chip.h>
62 #include <ti/csl/csl_semAux.h>
63 #include <ti/csl/csl_cacheAux.h>
64 #include <ti/csl/csl_xmcAux.h>
65 #endif
66 /* IPC includes */
67 /* #include <ti/ipc/GateMP.h>
68 #include <ti/ipc/Ipc.h>
69 #include <ti/ipc/ListMP.h>
70 #include <ti/ipc/SharedRegion.h> */
72 /**********************************************************************
73 ************************** Local Definitions *************************
74 **********************************************************************/
76 #define MCBSP_HW_SEM 1
77 #define PLATFORM_SPI_HW_SEM 2 /**< SPI BUS arbitration - Used by platform library */
79 #ifdef MCBSP_LOOP_PING_PONG
80 #define MAX_MEM_MGR_ENTRIES 8
81 #else
82 #define MAX_MEM_MGR_ENTRIES 4
83 #endif
85 typedef struct MEM_MGMT_ENTRY
86 {
87 uint8_t* ptrMemory;
88 uint32_t isFree;
89 }MEM_MGMT_ENTRY;
91 MEM_MGMT_ENTRY gDataBufferMemMgr[MAX_MEM_MGR_ENTRIES];
92 int32_t gDataBufferMemMgrMaxSize = 0;
94 /**********************************************************************
95 ************************** Global Variables **************************
96 **********************************************************************/
97 UInt32 malloc_counter = 0;
98 UInt32 free_counter = 0;
100 /**********************************************************************
101 ************************** Extern Definitions ************************
102 **********************************************************************/
105 /**********************************************************************
106 **************************** OSAL Functions **************************
107 **********************************************************************/
109 /**
110 * @b Description
111 * @n
112 * Utility function which converts a local address to global.
113 *
114 * @param[in] addr
115 * Local address to be converted
116 *
117 * @retval
118 * Global Address
119 */
120 void *Osal_local2Global (void *addr)
121 {
122 UInt32 corenum;
124 /* Get the core number. */
125 corenum = 0;//CSL_chipReadReg(CSL_CHIP_DNUM);
126 return addr;
128 if(((UInt32)addr & 0xff000000) == 0) {
129 /* Compute the global address. */
130 return ((void *)((UInt32)(addr) + (0x10000000 + (corenum*0x1000000))));
131 }
132 else
133 return(addr);
134 }
136 /**
137 * @b Description
138 * @n
139 * The function is used to allocate a memory block of the specified size.
140 *
141 * @param[in] numBytes
142 * Number of bytes to be allocated.
143 *
144 * @retval
145 * Allocated block address
146 */
147 Void* Osal_mcbspMalloc(UInt32 numBytes)
148 {
149 Error_Block errorBlock;
150 Void* ptr;
152 /* Increment the allocation counter. */
153 malloc_counter++;
155 /* Allocate the memory. */
156 ptr = Memory_alloc(NULL, numBytes, 0, &errorBlock);
158 /* Return the allocated memory block. */
159 return ptr;
160 }
162 /**
163 * @b Description
164 * @n
165 * The function is used to clean up a specific memory block and is called
166 * from the MCBSP Driver.
167 *
168 * @param[in] ptr
169 * Pointer to the memory block to be cleaned up.
170 * @param[in] size
171 * Size of the memory block being cleaned up.
172 *
173 * @retval
174 * Not Applicable
175 */
176 Void Osal_mcbspFree (Void* ptr, UInt32 size)
177 {
178 /* Increment the free counter. */
179 free_counter++;
180 Memory_free(NULL, ptr, size);
181 }
183 /**
184 * @b Description
185 * @n
186 * The function is used to allocate a block of memory for all the data buffer
187 * operations. This function is called by the application.
188 *
189 * @param[in] numBuffers
190 * Number of data buffers
191 * @param[in] dataBufferSize
192 * Size of each data buffer
193 *
194 * @retval
195 * Success - 0
196 * @retval
197 * Error - <0
198 */
199 int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize)
200 {
201 Error_Block errorBlock;
202 uint8_t* ptrMemory;
203 uint32_t index;
205 /* Allocate memory for all the data buffers */
206 ptrMemory = (uint8_t*)Memory_alloc(NULL, MAX_MEM_MGR_ENTRIES*dataBufferSize, 128, &errorBlock);
207 if (ptrMemory == NULL)
208 return -1;
210 /* Convert to a global address */
211 ptrMemory = Osal_local2Global(ptrMemory);
213 /* Now we chop up the memory and add it to the memory manager. */
214 for (index = 0; index < MAX_MEM_MGR_ENTRIES; index++)
215 {
216 /* Populate the data memory management entry. */
217 gDataBufferMemMgr[index].isFree = 1;
218 gDataBufferMemMgr[index].ptrMemory = ptrMemory;
220 /* Increment the memory to the next address */
221 ptrMemory = ptrMemory + dataBufferSize;
222 }
224 /* Remember the memory buffer size */
225 gDataBufferMemMgrMaxSize = dataBufferSize;
227 /* Memory Manager has been created. */
228 return 0;
229 }
231 /**
232 * @b Description
233 * @n
234 * The function is used to allocate a data buffer of the specified
235 * size. Data buffers should always be allocated from the global
236 * address space.
237 *
238 * @param[in] numBytes
239 * Number of bytes to be allocated.
240 *
241 * @retval
242 * Allocated block address
243 */
244 Void* Osal_mcbspDataBufferMalloc(UInt32 numBytes)
245 {
246 uint32_t index;
247 void* ptrMemory = NULL;
249 /* Basic Validation: Ensure that the memory size requested is within range. */
250 if (numBytes > gDataBufferMemMgrMaxSize)
251 return NULL;
253 /* Increment the allocation counter. */
254 malloc_counter++;
256 /* Lock out interrupts */
257 Hwi_disable();
259 /* Cycle through for a free entry. */
260 for (index = 0; index < MAX_MEM_MGR_ENTRIES; index++)
261 {
262 /* Check if the entry is free or not? */
263 if (gDataBufferMemMgr[index].isFree == 1)
264 {
265 /* Entry was free. We can use it. */
266 ptrMemory = gDataBufferMemMgr[index].ptrMemory;
268 /* Mark the entry as used. */
269 gDataBufferMemMgr[index].isFree = 0;
271 /* We have found a match. */
272 break;
273 }
274 }
276 /* Unlock interrupts. */
277 Hwi_enable();
279 /* Return the allocated memory. */
280 return ptrMemory;
281 }
283 /**
284 * @b Description
285 * @n
286 * The function is used to clean up a previously allocated data buffer
287 * block. All data buffers are in the global address space
288 *
289 * @param[in] ptr
290 * Pointer to the data buffer block to be cleaned up
291 * @param[in] size
292 * Size of the data buffer
293 *
294 * @retval
295 * Not Applicable
296 */
297 void Osal_mcbspDataBufferFree(void* ptr, uint32_t numBytes)
298 {
299 uint32_t index;
301 /* Increment the free counter. */
302 free_counter++;
304 /* Lock out interrupts */
305 Hwi_disable();
307 /* Cycle through and clean up */
308 for (index = 0; index < MAX_MEM_MGR_ENTRIES; index++)
309 {
310 /* Check if the entry is free or not? */
311 if (gDataBufferMemMgr[index].ptrMemory == (uint8_t*)ptr)
312 {
313 /* Mark the entry as free. */
314 gDataBufferMemMgr[index].isFree = 1;
316 /* We have found a match. */
317 break;
318 }
319 }
321 /* Unlock interrupts. */
322 Hwi_enable();
323 return;
324 }
326 /**
327 * @b Description
328 * @n
329 * The function is the MCBSP OSAL Logging API which logs
330 * the messages on the console.
331 *
332 * @param[in] fmt
333 * Formatted String.
334 *
335 * @retval
336 * Not Applicable
337 */
338 Void Osal_mcbspLog( String fmt, ... )
339 {
340 }
342 /**
343 * @b Description
344 * @n
345 * The function is used to create a critical section.
346 *
347 * @retval
348 * Semaphore Handle created
349 */
350 Void* Osal_mcbspCreateSem(Void)
351 {
352 return (Void*)Semaphore_create(0, NULL, NULL);
353 }
355 /**
356 * @b Description
357 * @n
358 * The function is used to delete a critical section.
359 *
360 * @param[in] semHandle
361 * Semaphore handle to be deleted
362 *
363 * @retval
364 * Not Applicable
365 */
366 Void Osal_mcbspDeleteSem(Void* semHandle)
367 {
368 Semaphore_delete(semHandle);
369 }
371 /**
372 * @b Description
373 * @n
374 * The function is used to pend on a semaphore
375 *
376 * @param[in] semHandle
377 * Semaphore handle on which the API will pend
378 *
379 * @retval
380 * Not Applicable
381 */
382 Void Osal_mcbspPendSem(Void* semHandle)
383 {
384 Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
385 }
387 /**
388 * @b Description
389 * @n
390 * The function is used to post a semaphore
391 *
392 * @param[in] semHandle
393 * Semaphore handle which will be posted
394 *
395 * @retval
396 * Not Applicable
397 */
398 Void Osal_mcbspPostSem(Void* semHandle)
399 {
400 Semaphore_post(semHandle);
401 }
403 /**
404 * @b Description
405 * @n
406 * This is the Multicore OSAL Implementation to protect the driver shared
407 * resources across multiple cores.
408 *
409 * @retval
410 * Semaphore Opaque Handle
411 */
412 void* Osal_mcbspEnterMultipleCoreCriticalSection(void)
413 {
414 /* Get the hardware semaphore */
415 // while ((CSL_semAcquireDirect (MCBSP_HW_SEM)) == 0);
416 return NULL;
417 }
419 /**
420 * @b Description
421 * @n
422 * The function is called to end the critical section which was protecting
423 * shared resources from access across multiple cores.
424 *
425 * @param[in] critSectHandle
426 * Semaphore opaque handle.
427 *
428 * @retval
429 * None
430 */
431 Void Osal_mcbspExitMultipleCoreCriticalSection(Void* critSectHandle)
432 {
433 //CSL_semReleaseSemaphore (MCBSP_HW_SEM);
434 }
436 /**
437 * @b Description
438 * @n
439 * The function is used to provide critical section to prevent access of shared
440 * resources from single core and multiple threads.
441 *
442 * @param[in] drvHandle
443 * Driver Handle which needs critical section to protect its resources.
444 *
445 * @retval
446 * Opaque handle
447 */
448 Void* Osal_mcbspEnterSingleCoreCriticalSection()
449 {
450 /* Disable interrupts */
451 return (Void*)Hwi_disable();
452 }
454 /**
455 * @b Description
456 * @n
457 * The function is called to end the critical section access of shared resources
458 * from single cores.
459 *
460 * @param[in] drvHandle
461 * Driver Handle which needed critical section to protect its resources.
462 * @param[in] critSectHandle
463 * Opaque handle retreived when the Single Core Protection Enter API was called
464 *
465 * @retval
466 * Not Applicable.
467 */
468 Void Osal_mcbspExitSingleCoreCriticalSection(Void* critSectHandle)
469 {
470 /* Driver Managed Configuration: We need to enable interrupts. */
471 Hwi_enable();
472 }
474 /**
475 * @b Description
476 * @n
477 * The function is used by the MCBSP driver to indicate that
478 * its about to access a block of memory and we need to ensure
479 * that the cache contents for this block are invalidated before
480 * we try and use it.
481 *
482 * @param[in] ptr
483 * Pointer to the buffer which is being accessed
484 * @param[in] size
485 * Size of the buffer which is to be accessed.
486 *
487 * @retval
488 * None
489 */
490 #include "ti/sysbios/hal/Cache.h"
491 void Osal_mcbspBeginMemAccess(void* ptr, uint32_t size)
492 {
493 UInt key;
495 /* Disable Interrupts */
496 key = Hwi_disable();
498 /* Cleanup the prefetch buffer also. */
499 //CSL_XMC_invalidatePrefetchBuffer();
501 /* Invalidate the cache. */
502 //CACHE_invL1d (ptr, size, CACHE_FENCE_WAIT);
504 Cache_inv ((void *) ptr,size, 0x7fff, 1);
506 /* Reenable Interrupts. */
507 Hwi_restore(key);
508 }
510 /**
511 * @b Description
512 * @n
513 * The function is used by the MCBSP driver to indicate that its
514 * ending access to a block of memory. We need to ensure that the
515 * contents of the cache are written back to the actual memory.
516 *
517 * @param[in] ptr
518 * Pointer to the buffer
519 * @param[in] size
520 * Size of the buffer
521 *
522 * @retval
523 * None
524 */
525 void Osal_mcbspEndMemAccess(void* ptr, uint32_t size)
526 {
527 UInt key;
529 /* Disable Interrupts */
530 key = Hwi_disable();
532 /* Writeback the cache. */
533 //CACHE_wbL1d (ptr, size, CACHE_FENCE_WAIT);
534 Cache_wb ((void *) ptr,size, 0x7fff, 1);
535 /* Reenable Interrupts. */
536 Hwi_restore(key);
537 }
539 /**
540 * @brief The function is used by the MCBSP driver to test for an
541 * empty queue.
542 *
543 * <b> Parameter </b>
544 * @n handle - Handle of a previously created Queue instance object
545 *
546 * <b> Return Value </b>
547 * @n TRUE - If the queue is empty
548 */
549 Bool Osal_mcbspQueueEmpty(void* handle)
550 {
551 return Queue_empty(handle);
552 }
554 /**
555 * @brief The macro is used by the MCBSP driver to get an
556 * element from the front of queue. The function
557 * removes the element from the front of queue and
558 * returns a pointer to it.
559 *
560 * <b> Parameter </b>
561 * @n handle - Handle of a previously created Queue instance object
562 *
563 * <b> Return Value </b>
564 * @n Handle (pointer) to former first element
565 */
566 void* Osal_mcbspQueueGet(void* handle)
567 {
568 return Queue_get(handle);
569 }
571 /**
572 * @brief The macro is used by the MCBSP driver to put an
573 * element at the end of queue.
574 *
575 * <b> Parameter </b>
576 * @n handle - Handle of a previously created Queue instance object
577 * @n elem - Pointer to new queue element
578 *
579 * <b> Return Value </b>
580 * @n None
581 */
582 void Osal_mcbspQueuePut(void* handle, Mcbsp_QueueElem* elem)
583 {
584 Queue_put(handle, (Queue_Elem *)elem);
585 return;
586 }
588 /**
589 * @brief The macro is used by the MCBSP driver to wait 'n'
590 * bit clocks to ensure proper synchronization internally.
591 *
592 * <b> Parameter </b>
593 * @n nticks - Number of bit clocks to wait
594 *
595 * <b> Return Value </b>
596 * @n None
597 */
598 void Osal_mcbspWaitNBitClocks(uint32_t nticks)
599 {
600 //Task_sleep(nticks);
601 int i=0;
602 for (i=0; i<100; i++);
603 return;
604 }
606 /* OSAL functions for Platform Library */
607 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
608 {
609 return malloc(num_bytes);
610 }
612 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
613 {
614 /* Free up the memory */
615 if (dataPtr)
616 {
617 free(dataPtr);
618 }
619 }
621 void Osal_platformSpiCsEnter(void)
622 {
623 /* Get the hardware semaphore.
624 *
625 * Acquire Multi core CPPI synchronization lock
626 */
627 //while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);
629 return;
630 }
632 void Osal_platformSpiCsExit (void)
633 {
634 /* Release the hardware semaphore
635 *
636 * Release multi-core lock.
637 */
638 //CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);
640 return;
641 }