TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

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(PC_13, PC_6, PE_5, PE_4, PE_6, SPI(PB_5, PB_4, PB_3));
00053 
00054 
00055 typedef struct _SlInternalSpawnEntry_t {
00056     _SlSpawnEntryFunc_t                 pEntry;
00057     void*                               pValue;
00058     struct _SlInternalSpawnEntry_t*     pNext;
00059 } _SlInternalSpawnEntry_t;
00060 
00061 typedef struct {
00062     _SlInternalSpawnEntry_t     SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES];
00063     _SlInternalSpawnEntry_t*    pFree;
00064     _SlInternalSpawnEntry_t*    pWaitForExe;
00065     _SlInternalSpawnEntry_t*    pLastInWaitList;
00066     _SlSyncObj_t                SyncObj;
00067     _SlLockObj_t                LockObj;
00068 } _SlInternalSpawnCB_t;
00069 
00070 _SlInternalSpawnCB_t g_SlInternalSpawnCB;
00071 
00072 //cc3100_spawn::cc3100_spawn()
00073 //{
00074 
00075 //}
00076 
00077 //cc3100_spawn::~cc3100_spawn()
00078 //{
00079 
00080 //}
00081 
00082 
00083 void /*cc3100_spawn::*/_SlInternalSpawnTaskEntry()
00084 {
00085     int16_t                     i;
00086     _SlInternalSpawnEntry_t*    pEntry;
00087     uint8_t                     LastEntry;
00088 
00089     /* create and lock the locking object. lock in order to avoid race condition
00090         on the first creation */
00091     sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect");
00092     sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT);
00093 
00094     /* create and clear the sync object */
00095     sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
00096     sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
00097 
00098     g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0];
00099     g_SlInternalSpawnCB.pWaitForExe = NULL;
00100     g_SlInternalSpawnCB.pLastInWaitList = NULL;
00101 
00102     /* create the link list between the entries */
00103     for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) {
00104         g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1];
00105         g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL;
00106     }
00107     g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL;
00108 
00109     _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00110 
00111 
00112     /* here we ready to execute entries */
00113 
00114     while (TRUE) {
00115         sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER);
00116         /* go over all entries that already waiting for execution */
00117         LastEntry = FALSE;
00118         do {
00119             /* get entry to execute */
00120             _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00121 
00122             pEntry = g_SlInternalSpawnCB.pWaitForExe;
00123             if ( NULL == pEntry ) {
00124                 _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00125                 break;
00126             }
00127             g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext;
00128             if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) {
00129                 g_SlInternalSpawnCB.pLastInWaitList = NULL;
00130                 LastEntry = TRUE;
00131             }
00132 
00133             _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00134 
00135 
00136             /* pEntry could be null in case that the sync was already set by some
00137                of the entries during execution of earlier entry */
00138             if (NULL != pEntry) {
00139                 pEntry->pEntry(pEntry->pValue);
00140                 /* free the entry */
00141                 _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00142 
00143                 pEntry->pNext = g_SlInternalSpawnCB.pFree;
00144                 g_SlInternalSpawnCB.pFree = pEntry;
00145 
00146 
00147                 if (NULL != g_SlInternalSpawnCB.pWaitForExe) {
00148                     /* new entry received meanwhile */
00149                     LastEntry = FALSE;
00150                 }
00151 
00152                 _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00153 
00154             }
00155 
00156         } while (!LastEntry);
00157     }
00158 }
00159 
00160 
00161 int16_t /*cc3100_spawn::*/_SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , uint32_t flags)
00162 {
00163     int16_t                         Res = 0;
00164     _SlInternalSpawnEntry_t*    pSpawnEntry;
00165 
00166     if (NULL == pEntry) {
00167         Res = -1;
00168     } else {
00169          _cc3100._driver._SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00170 
00171         pSpawnEntry = g_SlInternalSpawnCB.pFree;
00172         g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext;
00173 
00174         pSpawnEntry->pEntry = pEntry;
00175         pSpawnEntry->pValue = pValue;
00176         pSpawnEntry->pNext = NULL;
00177 
00178         if (NULL == g_SlInternalSpawnCB.pWaitForExe) {
00179             g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry;
00180             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00181         } else {
00182             g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry;
00183             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00184         }
00185 
00186         _cc3100._driver._SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00187         
00188         /* this sync is called after releasing the lock object to avoid unnecessary context switches */
00189         _cc3100._driver._SlDrvSyncObjSignal(&g_SlInternalSpawnCB.SyncObj);
00190     }
00191 
00192     return Res;
00193 }
00194 
00195 }//namespace mbed_cc3100
00196 
00197 #endif//SL_PLATFORM_MULTI_THREADED
00198