Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

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