David Fletcher / Mbed 2 deprecated cc3100_Test_websock_Camera_CM4F

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_spawn.cpp Source File

cc3100_spawn.cpp

00001 /*
00002  * spawn.c - CC31xx/CC32xx Host Driver Implementation
00003  *
00004  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
00005  *
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *    Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  *    Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  *    Neither the name of Texas Instruments Incorporated nor the names of
00020  *    its contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035 */
00036 
00037 
00038 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 
00044 #include "cc3100_spawn.h"
00045 
00046 #if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00047 
00048 namespace mbed_cc3100 {
00049 
00050 #define _SL_MAX_INTERNAL_SPAWN_ENTRIES      10
00051 
00052 cc3100 _cc3100(NC, NC, PD_12, PD_13, PD_11, SPI(PC_3, PC_2, PB_10));//Seeed_Arch_Max  irq, nHib, cs, mosi, miso, sck
00053 
00054 typedef struct _SlInternalSpawnEntry_t {
00055     _SlSpawnEntryFunc_t                 pEntry;
00056     void*                               pValue;
00057     struct _SlInternalSpawnEntry_t*     pNext;
00058 } _SlInternalSpawnEntry_t;
00059 
00060 typedef struct {
00061     _SlInternalSpawnEntry_t     SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES];
00062     _SlInternalSpawnEntry_t*    pFree;
00063     _SlInternalSpawnEntry_t*    pWaitForExe;
00064     _SlInternalSpawnEntry_t*    pLastInWaitList;
00065     _SlSyncObj_t                SyncObj;
00066     _SlLockObj_t                LockObj;
00067 } _SlInternalSpawnCB_t;
00068 
00069 _SlInternalSpawnCB_t g_SlInternalSpawnCB;
00070 
00071 //cc3100_spawn::cc3100_spawn()
00072 //{
00073 
00074 //}
00075 
00076 //cc3100_spawn::~cc3100_spawn()
00077 //{
00078 
00079 //}
00080 
00081 
00082 void /*cc3100_spawn::*/_SlInternalSpawnTaskEntry()
00083 {
00084     int16_t                     i;
00085     _SlInternalSpawnEntry_t*    pEntry;
00086     uint8_t                     LastEntry;
00087 
00088     /* create and lock the locking object. lock in order to avoid race condition
00089         on the first creation */
00090     sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect");
00091     sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT);
00092 
00093     /* create and clear the sync object */
00094     sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
00095     sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
00096 
00097     g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0];
00098     g_SlInternalSpawnCB.pWaitForExe = NULL;
00099     g_SlInternalSpawnCB.pLastInWaitList = NULL;
00100 
00101     /* create the link list between the entries */
00102     for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) {
00103         g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1];
00104         g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL;
00105     }
00106     g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL;
00107 
00108     _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00109 
00110 
00111     /* here we ready to execute entries */
00112 
00113     while (TRUE) {
00114         sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER);
00115         /* go over all entries that already waiting for execution */
00116         LastEntry = FALSE;
00117         do {
00118             /* get entry to execute */
00119             _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00120 
00121             pEntry = g_SlInternalSpawnCB.pWaitForExe;
00122             if ( NULL == pEntry ) {
00123                 _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00124                 break;
00125             }
00126             g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext;
00127             if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) {
00128                 g_SlInternalSpawnCB.pLastInWaitList = NULL;
00129                 LastEntry = TRUE;
00130             }
00131 
00132             _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00133 
00134 
00135             /* pEntry could be null in case that the sync was already set by some
00136                of the entries during execution of earlier entry */
00137             if (NULL != pEntry) {
00138                 pEntry->pEntry(pEntry->pValue);
00139                 /* free the entry */
00140                 _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00141 
00142                 pEntry->pNext = g_SlInternalSpawnCB.pFree;
00143                 g_SlInternalSpawnCB.pFree = pEntry;
00144 
00145 
00146                 if (NULL != g_SlInternalSpawnCB.pWaitForExe) {
00147                     /* new entry received meanwhile */
00148                     LastEntry = FALSE;
00149                 }
00150 
00151                 _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00152 
00153             }
00154 
00155         } while (!LastEntry);
00156     }
00157 }
00158 
00159 
00160 int16_t /*cc3100_spawn::*/_SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , uint32_t flags)
00161 {
00162     int16_t                         Res = 0;
00163     _SlInternalSpawnEntry_t*    pSpawnEntry;
00164 
00165     if (NULL == pEntry) {
00166         Res = -1;
00167     } else {
00168          _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00169 
00170         pSpawnEntry = g_SlInternalSpawnCB.pFree;
00171         g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext;
00172 
00173         pSpawnEntry->pEntry = pEntry;
00174         pSpawnEntry->pValue = pValue;
00175         pSpawnEntry->pNext = NULL;
00176 
00177         if (NULL == g_SlInternalSpawnCB.pWaitForExe) {
00178             g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry;
00179             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00180         } else {
00181             g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry;
00182             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00183         }
00184 
00185         _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00186         
00187         /* this sync is called after releasing the lock object to avoid unnecessary context switches */
00188         _cc3100._driver._SlDrvSyncObjSignal(&g_SlInternalSpawnCB.SyncObj);
00189     }
00190 
00191     return Res;
00192 }
00193 
00194 }//namespace mbed_cc3100
00195 
00196 #endif//SL_PLATFORM_MULTI_THREADED
00197