[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1 / packages / ti / platform / evmk2g / platform_audio_test / digital / loopback / src / sample_cs.c
diff --git a/pdk_k2g_1_0_1/packages/ti/platform/evmk2g/platform_audio_test/digital/loopback/src/sample_cs.c b/pdk_k2g_1_0_1/packages/ti/platform/evmk2g/platform_audio_test/digital/loopback/src/sample_cs.c
--- /dev/null
+++ b/pdk_k2g_1_0_1/packages/ti/platform/evmk2g/platform_audio_test/digital/loopback/src/sample_cs.c
@@ -0,0 +1,421 @@
+/*
+ * sample_cs.c
+ *
+ * Sample functions showing the implementation of critical section entry/exit
+ * routines and various semaphore related routines (all BIOS6 depenedent).
+ * These implementations MUST be provided by the user / application, using the
+ * EDMA3 driver, for its correct functioning.
+ *
+ * Copyright (C) 2009-2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+#include <ti/sysbios/family/c64p/EventCombiner.h>
+#include <ti/sysbios/hal/Cache.h>
+#include <ti/sysbios/hal/Hwi.h>
+#include <ti/sysbios/knl/Task.h>
+#include <ti/sysbios/knl/Semaphore.h>
+
+#include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h>
+#include <ti/sdo/edma3/drv/edma3_drv.h>
+
+extern unsigned int ccXferCompInt[][EDMA3_MAX_REGIONS];
+extern unsigned int ccErrorInt[];
+extern unsigned int tcErrorInt[][EDMA3_MAX_TC];
+
+/**
+ * Shadow Region on which the executable is running. Its value is
+ * populated with the DSP Instance Number here in this case.
+ */
+extern unsigned int region_id;
+
+/**
+ * \brief EDMA3 OS Protect Entry
+ *
+ * This function saves the current state of protection in 'intState'
+ * variable passed by caller, if the protection level is
+ * EDMA3_OS_PROTECT_INTERRUPT. It then applies the requested level of
+ * protection.
+ * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
+ * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
+ * and the requested interrupt is disabled.
+ * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, '*intState' specifies the
+ * Transfer Controller number whose interrupt needs to be disabled.
+ *
+ * \param level is numeric identifier of the desired degree of protection.
+ * \param intState is memory location where current state of protection is
+ * saved for future use while restoring it via edma3OsProtectExit() (Only
+ * for EDMA3_OS_PROTECT_INTERRUPT protection level).
+ * \return None
+ */
+void edma3OsProtectEntry (unsigned int edma3InstanceId,
+ int level, unsigned int *intState)
+ {
+ if (((level == EDMA3_OS_PROTECT_INTERRUPT)
+ || (level == EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR))
+ && (intState == NULL))
+ {
+ return;
+ }
+ else
+ {
+ switch (level)
+ {
+ /* Disable all (global) interrupts */
+ case EDMA3_OS_PROTECT_INTERRUPT :
+ *intState = Hwi_disable();
+ break;
+
+ /* Disable scheduler */
+ case EDMA3_OS_PROTECT_SCHEDULER :
+ Task_disable();
+ break;
+
+ /* Disable EDMA3 transfer completion interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
+ EventCombiner_disableEvent(ccXferCompInt[edma3InstanceId][region_id]);
+ break;
+
+ /* Disable EDMA3 CC error interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
+ EventCombiner_disableEvent(ccErrorInt[edma3InstanceId]);
+ break;
+
+ /* Disable EDMA3 TC error interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
+ switch (*intState)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ /* Fall through... */
+ /* Disable the corresponding interrupt */
+ EventCombiner_disableEvent(tcErrorInt[edma3InstanceId][*intState]);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+
+/**
+ * \brief EDMA3 OS Protect Exit
+ *
+ * This function undoes the protection enforced to original state
+ * as is specified by the variable 'intState' passed, if the protection
+ * level is EDMA3_OS_PROTECT_INTERRUPT.
+ * For EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION and
+ * EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR, variable 'intState' is ignored,
+ * and the requested interrupt is enabled.
+ * For EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR, 'intState' specifies the
+ * Transfer Controller number whose interrupt needs to be enabled.
+ * \param level is numeric identifier of the desired degree of protection.
+ * \param intState is original state of protection at time when the
+ * corresponding edma3OsProtectEntry() was called (Only
+ * for EDMA3_OS_PROTECT_INTERRUPT protection level).
+ * \return None
+ */
+void edma3OsProtectExit (unsigned int edma3InstanceId,
+ int level, unsigned int intState)
+ {
+ switch (level)
+ {
+ /* Enable all (global) interrupts */
+ case EDMA3_OS_PROTECT_INTERRUPT :
+ Hwi_restore(intState);
+ break;
+
+ /* Enable scheduler */
+ case EDMA3_OS_PROTECT_SCHEDULER :
+ Task_enable();
+ break;
+
+ /* Enable EDMA3 transfer completion interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION :
+ EventCombiner_enableEvent(ccXferCompInt[edma3InstanceId][region_id]);
+ break;
+
+ /* Enable EDMA3 CC error interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR :
+ EventCombiner_enableEvent(ccErrorInt[edma3InstanceId]);
+ break;
+
+ /* Enable EDMA3 TC error interrupt only */
+ case EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR :
+ switch (intState)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ /* Fall through... */
+ /* Enable the corresponding interrupt */
+ EventCombiner_enableEvent(tcErrorInt[edma3InstanceId][intState]);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+/**
+ * \brief EDMA3 Cache Invalidate
+ *
+ * This function invalidates the D cache.
+ *
+ * \param mem_start_ptr [IN] Starting address of memory.
+ * Please note that this should be
+ * aligned according to the cache line size.
+ * \param num_bytes [IN] length of buffer
+ * \return EDMA3_DRV_SOK if success, else error code in case of error
+ * or non-alignment of buffers.
+ *
+ * Note: This function is required if the buffer is in DDR.
+ * For other cases, where buffer is NOT in DDR, user
+ * may or may not require the below implementation and
+ * should modify it according to her need.
+ */
+EDMA3_DRV_Result Edma3_CacheInvalidate(unsigned int mem_start_ptr,
+ unsigned int num_bytes)
+ {
+ EDMA3_DRV_Result cacheInvResult = EDMA3_DRV_SOK;
+
+ /* Verify whether the start address is cache aligned or not */
+ if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u)) != 0)
+ {
+#ifdef EDMA3_DRV_DEBUG
+ EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
+ EDMA3_CACHE_LINE_SIZE_IN_BYTES);
+#endif
+ cacheInvResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
+ }
+ else
+ {
+ Cache_inv((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
+ }
+
+ return cacheInvResult;
+}
+
+
+
+/**
+ * \brief EDMA3 Cache Flush
+ *
+ * This function flushes (cleans) the Cache
+ *
+ * \param mem_start_ptr [IN] Starting address of memory.
+ * Please note that this should be
+ * aligned according to the cache line size.
+ * \param num_bytes [IN] length of buffer
+ * \return EDMA3_DRV_SOK if success, else error code in case of error
+ * or non-alignment of buffers.
+ *
+ * Note: This function is required if the buffer is in DDR.
+ * For other cases, where buffer is NOT in DDR, user
+ * may or may not require the below implementation and
+ * should modify it according to her need.
+ */
+EDMA3_DRV_Result Edma3_CacheFlush(unsigned int mem_start_ptr,
+ unsigned int num_bytes)
+ {
+ EDMA3_DRV_Result cacheFlushResult = EDMA3_DRV_SOK;
+
+ /* Verify whether the start address is cache aligned or not */
+ if((mem_start_ptr & (EDMA3_CACHE_LINE_SIZE_IN_BYTES-1u)) != 0)
+ {
+#ifdef EDMA3_DRV_DEBUG
+ EDMA3_DRV_PRINTF("\r\n Cache : Memory is not %d bytes alinged\r\n",
+ EDMA3_CACHE_LINE_SIZE_IN_BYTES);
+#endif
+ cacheFlushResult = EDMA3_NON_ALIGNED_BUFFERS_ERROR;
+ }
+ else
+ {
+ Cache_wb((Ptr)mem_start_ptr, num_bytes, Cache_Type_ALL, TRUE);
+ }
+
+ return cacheFlushResult;
+}
+
+
+/**
+ * Counting Semaphore related functions (OS dependent) should be
+ * called/implemented by the application. A handle to the semaphore
+ * is required while opening the driver/resource manager instance.
+ */
+
+/**
+ * \brief EDMA3 OS Semaphore Create
+ *
+ * This function creates a counting semaphore with specified
+ * attributes and initial value. It should be used to create a semaphore
+ * with initial value as '1'. The semaphore is then passed by the user
+ * to the EDMA3 driver/RM for proper sharing of resources.
+ * \param initVal [IN] is initial value for semaphore
+ * \param semParams [IN] is the semaphore attributes.
+ * \param hSem [OUT] is location to recieve the handle to just created
+ * semaphore
+ * \return EDMA3_DRV_SOK if succesful, else a suitable error code.
+ */
+EDMA3_DRV_Result edma3OsSemCreate(int initVal,
+ const Semaphore_Params *semParams,
+ EDMA3_OS_Sem_Handle *hSem)
+ {
+ EDMA3_DRV_Result semCreateResult = EDMA3_DRV_SOK;
+
+ if(NULL == hSem)
+ {
+ semCreateResult = EDMA3_DRV_E_INVALID_PARAM;
+ }
+ else
+ {
+ *hSem = (EDMA3_OS_Sem_Handle)Semaphore_create(initVal, semParams, NULL);
+ if ( (*hSem) == NULL )
+ {
+ semCreateResult = EDMA3_DRV_E_SEMAPHORE;
+ }
+ }
+
+ return semCreateResult;
+ }
+
+
+/**
+ * \brief EDMA3 OS Semaphore Delete
+ *
+ * This function deletes or removes the specified semaphore
+ * from the system. Associated dynamically allocated memory
+ * if any is also freed up.
+ * \param hSem [IN] handle to the semaphore to be deleted
+ * \return EDMA3_DRV_SOK if succesful else a suitable error code
+ */
+EDMA3_DRV_Result edma3OsSemDelete(EDMA3_OS_Sem_Handle hSem)
+ {
+ EDMA3_DRV_Result semDeleteResult = EDMA3_DRV_SOK;
+
+ if(NULL == hSem)
+ {
+ semDeleteResult = EDMA3_DRV_E_INVALID_PARAM;
+ }
+ else
+ {
+ Semaphore_delete((Semaphore_Handle *)&hSem);
+ }
+
+ return semDeleteResult;
+ }
+
+
+/**
+ * \brief EDMA3 OS Semaphore Take
+ *
+ * This function takes a semaphore token if available.
+ * If a semaphore is unavailable, it blocks currently
+ * running thread in wait (for specified duration) for
+ * a free semaphore.
+ * \param hSem [IN] is the handle of the specified semaphore
+ * \param mSecTimeout [IN] is wait time in milliseconds
+ * \return EDMA3_DRV_Result if successful else a suitable error code
+ */
+EDMA3_DRV_Result edma3OsSemTake(EDMA3_OS_Sem_Handle hSem, int mSecTimeout)
+ {
+ EDMA3_DRV_Result semTakeResult = EDMA3_DRV_SOK;
+ unsigned short semPendResult;
+
+ if(NULL == hSem)
+ {
+ semTakeResult = EDMA3_DRV_E_INVALID_PARAM;
+ }
+ else
+ {
+ semPendResult = Semaphore_pend(hSem, mSecTimeout);
+ if (semPendResult == FALSE)
+ {
+ semTakeResult = EDMA3_DRV_E_SEMAPHORE;
+ }
+ }
+
+ return semTakeResult;
+ }
+
+
+/**
+ * \brief EDMA3 OS Semaphore Give
+ *
+ * This function gives or relinquishes an already
+ * acquired semaphore token
+ * \param hSem [IN] is the handle of the specified semaphore
+ * \return EDMA3_DRV_Result if successful else a suitable error code
+ */
+EDMA3_DRV_Result edma3OsSemGive(EDMA3_OS_Sem_Handle hSem)
+ {
+ EDMA3_DRV_Result semGiveResult = EDMA3_DRV_SOK;
+
+ if(NULL == hSem)
+ {
+ semGiveResult = EDMA3_DRV_E_INVALID_PARAM;
+ }
+ else
+ {
+ Semaphore_post(hSem);
+ }
+
+ return semGiveResult;
+ }
+
+/* End of File */
+