/* * ======== WiFiCC3100_spiCallbackFxn ======== * Callback function for when the SPI has completed a transfer * * @pre Function assumes that the handle is not NULL */ static void WiFiCC3100_spiCallbackFxn(SPI_Handle spiHandle, SPI_Transaction *transaction) { WiFiCC3100_Object *object = wifiHandle->object; switch (object->spiState) { case WiFiCC3100_SPI_WRITE_MSG: Semaphore_post(Semaphore_handle(&(object->writeSemaphore))); break; case WiFiCC3100_SPI_WRITE_EOT: object->spiState = WiFiCC3100_SPI_IDLE; Semaphore_post(Semaphore_handle(&(object->writeSemaphore))); break; case WiFiCC3100_SPI_READ_MSG: Semaphore_post(Semaphore_handle(&(object->readSemaphore))); break; case WiFiCC3100_SPI_READ_EOT: object->spiState = WiFiCC3100_SPI_IDLE; Semaphore_post(Semaphore_handle(&(object->readSemaphore))); break; default: break; } }
/******************************************************************************* * @fn bspI2cSelect * * @brief Select an I2C interface and slave * * @param newInterface - selected interface * @param address - slave address * * @return true if success */ bool bspI2cSelect(uint8_t newInterface, uint8_t address) { // Acquire I2C resource if (!Semaphore_pend(Semaphore_handle(&mutex),MS_2_TICKS(I2C_TIMEOUT))) { return false; } // Store new slave address slaveAddr = address; // Interface changed ? if (newInterface != interface) { // Store new interface interface = newInterface; // Shut down RTOS driver I2C_close(i2cHandle); // Sets custom to NULL, selects I2C interface 0 I2C_Params_init(&i2cParams); // Assign I2C data/clock pins according to selected I2C interface 1 if (interface == BSP_I2C_INTERFACE_1) { i2cParams.custom = (void*)&pinCfg1; } // Re-open RTOS driver with new bus pin assignment i2cHandle = I2C_open(Board_I2C, &i2cParams); } return true; }
/* * ======== pthread_exit ======== */ void pthread_exit(void *retval) { pthread_Obj *thread = (pthread_Obj *)pthread_self(); /* * This function terminates the calling thread and returns * a value via retval that (if the thread is joinable) is available to * another thread that calls pthread_join(). * * Any clean-up handlers that have not yet been popped, are popped * (in the reverse of the order in which they were pushed) and executed. */ thread->ret = retval; /* * Don't bother disabling the Task scheduler while the thread * is exiting. It will be up to the application to not make * such calls as pthread_cancel() or pthread_detach() while the * thread is exiting. */ /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys((pthread_t)thread); if (!thread->detached) { Semaphore_post(Semaphore_handle(&(thread->joinSem))); /* Set this task's priority to -1 to stop it from running. */ Task_setPri(thread->task, -1); } else { /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); /* * Don't call Task_delete on the calling thread. Task_exit() * will put the task on the terminated queue, and if * Task_deleteTerminatedTasks is TRUE, the task will be cleaned * up automatically. */ Task_exit(); } }
void bspI2cDeselect(void) { #ifdef POWER_SAVING /* Allow the system to enter standby */ if (checkI2cConstraint) { Power_releaseConstraint(Power_SB_DISALLOW); checkI2cConstraint = false; } #endif /* Release I2C resource */ Semaphore_post(Semaphore_handle(&mutex)); }
/* * ======== SPICC26XXDMA_transferCallback ======== * Callback function for when the SPI is in SPI_MODE_BLOCKING * * @pre Function assumes that the handle is not NULL */ static void SPICC26XXDMA_transferCallback(SPI_Handle handle, SPI_Transaction *msg) { SPICC26XX_Object *object; Log_print1(Diags_USER1, "SPI DMA:(%p) posting transferComplete semaphore", ((SPICC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); /* Get the pointer to the object */ object = handle->object; /* Post the semaphore */ Semaphore_post(Semaphore_handle(&(object->transferComplete))); }
/* * ======== pthread_cancel ======== * The specification of this API is that it be used as a means for one thread * to termintate the execution of another thread. There is no mention of * returning an error if the argument, pthread, is the same thread as the * calling thread. */ int pthread_cancel(pthread_t pthread) { pthread_Obj *thread = (pthread_Obj *)pthread; UInt key; /* * Cancel the thread. Only asynchronous cancellation is supported, * since functions that would normally be cancellation points (eg, * printf()), are not cancellation points for BIOS. */ key = Task_disable(); /* Indicate that cancellation is requested. */ thread->cancelPending = 1; if (thread->cancelState == PTHREAD_CANCEL_ENABLE) { /* Set this task's priority to -1 to stop it from running. */ Task_setPri(thread->task, -1); Task_restore(key); /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys(pthread); if (thread->detached) { /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Task_delete(&(thread->task)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); } else { /* pthread_join() will clean up. */ thread->ret = PTHREAD_CANCELED; Semaphore_post(Semaphore_handle(&(thread->joinSem))); } } else { Task_restore(key); } return (0); }
/* * ======== I2CCC26XX_blockingCallback ======== */ static void I2CCC26XX_blockingCallback(I2C_Handle handle, I2C_Transaction *msg, bool transferStatus) { I2CCC26XX_Object *object; Log_print1(Diags_USER1, "I2C:(%p) posting transferComplete semaphore", ((I2CCC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); /* Get the pointer to the object */ object = handle->object; /* Indicate transfer complete */ Semaphore_post(Semaphore_handle(&(object->transferComplete))); }
/******************************************************************************* * @fn bspI2cReset * * @brief Reset the RTOS I2C driver * * @param none * * @return none */ void bspI2cReset(void) { // Acquire I2C resource */ if (!Semaphore_pend(Semaphore_handle(&mutex),MS_2_TICKS(I2C_TIMEOUT))) { return; } // Close the driver I2C_close(i2cHandle); // Reset the I2C controller HapiResetPeripheral(PRCM_PERIPH_I2C0); // Reset local variables slaveAddr = 0xFF; interface = BSP_I2C_INTERFACE_0; // Open driver i2cHandle = I2C_open(Board_I2C, &i2cParams); // Release I2C resource Semaphore_post(Semaphore_handle(&mutex)); }
void bspI2cSelect(uint8_t newInterface, uint8_t address) { /* Acquire I2C resource */ Semaphore_pend(Semaphore_handle(&mutex),BIOS_WAIT_FOREVER); #ifdef POWER_SAVING if (!checkI2cConstraint) { /* Prevent the system from entering standby while using I2C. */ Power_setConstraint(Power_SB_DISALLOW); checkI2cConstraint = true; } #endif slaveAddr = address; if (newInterface != interface) { interface = newInterface; I2C_close(I2Chandle); if (interface == BSP_I2C_INTERFACE_0) { i2cCC26xxHWAttrs[CC2650_I2C0].sdaPin = Board_I2C0_SDA0; i2cCC26xxHWAttrs[CC2650_I2C0].sclPin = Board_I2C0_SCL0; // Secondary I2C as GPIO IOCPinTypeGpioInput(Board_I2C0_SDA1); IOCPinTypeGpioInput(Board_I2C0_SCL1); IOCIOPortPullSet(Board_I2C0_SDA1, IOC_NO_IOPULL); IOCIOPortPullSet(Board_I2C0_SCL1, IOC_NO_IOPULL); } else if (interface == BSP_I2C_INTERFACE_1) { i2cCC26xxHWAttrs[CC2650_I2C0].sdaPin = Board_I2C0_SDA1; i2cCC26xxHWAttrs[CC2650_I2C0].sclPin = Board_I2C0_SCL1; // Primary I2C as GPIO IOCPinTypeGpioInput(Board_I2C0_SDA0); IOCPinTypeGpioInput(Board_I2C0_SCL0); IOCIOPortPullSet(Board_I2C0_SDA0, IOC_NO_IOPULL); IOCIOPortPullSet(Board_I2C0_SCL0, IOC_NO_IOPULL); } I2Chandle = I2C_open(Board_I2C, &I2CParams); } }
/* * ======== _pthread_runStub ======== */ static void _pthread_runStub(UArg arg0, UArg arg1) { UInt key; Ptr arg; pthread_Obj *thread = (pthread_Obj *)(xdc_uargToPtr(arg1)); arg = Task_getEnv(thread->task); thread->ret = thread->fxn(arg); /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys((pthread_t)thread); key = Task_disable(); if (!thread->detached) { Semaphore_post(Semaphore_handle(&(thread->joinSem))); /* * Set this task's priority to -1 to prevent it from being put * on the terminated queue (and deleted if Task.deleteTerminatedTasks * is true). pthread_join() will delete the Task object. */ Task_setPri(thread->task, -1); Task_restore(key); } else { Task_restore(key); /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); /* The system will have to clean up the Task object */ } /* Task_exit() is called when returning from this function */ }
/* * ======== pthread_join ======== * Wait for thread to terminate. * * If multiple threads simultaneously try to join with the same * thread, the results are undefined. We will return an error. * * If the thread calling pthread_join() is canceled, then the target * thread will remain joinable (i.e., it will not be detached). */ int pthread_join(pthread_t pthread, void **thread_return) { pthread_Obj *thread = (pthread_Obj *)pthread; UInt key; key = Task_disable(); if ((thread->joinThread != NULL) || (thread->detached != 0)) { /* * Error - Another thread has already called pthread_join() * for this thread, or the thread is in the detached state. */ Task_restore(key); return (EINVAL); } if (pthread == pthread_self()) { Task_restore(key); return (EDEADLK); } /* * Allow pthread_join() to be called from a BIOS Task. If we * set joinThread to pthread_self(), we could get NULL if the * Task arg1 is 0. All we need is a non-NULL value for joinThread. */ thread->joinThread = Task_self(); Task_restore(key); Semaphore_pend(Semaphore_handle(&(thread->joinSem)), BIOS_WAIT_FOREVER); if (thread_return) { *thread_return = thread->ret; } #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Task_delete(&(thread->task)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); return (0); }
/* * ======== USBMSCHFatFsTiva_waitForConnect ======== */ bool USBMSCHFatFsTiva_waitForConnect(USBMSCHFatFs_Handle handle, unsigned int timeout) { unsigned int key; bool ret = true; USBMSCHFatFsTiva_Object *object = handle->object; /* Need exclusive access to prevent a race condition */ key = GateMutex_enter(GateMutex_handle(&(object->gateUSBWait))); if (object->state == USBMSCHFatFsTiva_NO_DEVICE) { if (!Semaphore_pend(Semaphore_handle(&(object->semUSBConnected)), timeout)) { ret = false; } } GateMutex_leave(GateMutex_handle(&(object->gateUSBWait)), key); return (ret); }
/* * ======== USBMSCHFatFsTiva_cbMSCHandler ======== * Callback handler for the USB stack. * * Callback handler call by the USB stack to notify us on what has * happened in regards to the mouse. This is done in a context of the priority * of the USBMSCHFatFsTiva_serviceUSBHost task. * * @param instance A driver instance of MSC. * * @param event Identifies the event that occurred in regards to this * device. * * @param eventMsgPtr A data pointer associated with a particular event. */ static void USBMSCHFatFsTiva_cbMSCHandler(USBMSCType instance, USBMSCEventType event, void *eventMsgPtr) { USBMSCHFatFsTiva_Object *object = USBMSCHFatFs_config->object; /* Determine what event has happened */ switch (event) { case MSC_EVENT_OPEN: object->state = USBMSCHFatFsTiva_CONNECTED; Log_print0(Diags_USER2, "USBMSCHFatFs: MSC DEVICE CONNECTED; " "Posting semUSBConnected"); Semaphore_post(Semaphore_handle(&object->semUSBConnected)); break; case MSC_EVENT_CLOSE: object->state = USBMSCHFatFsTiva_NO_DEVICE; Log_print0(Diags_USER2, "USBMSCHFatFs: MSC DEVICE DISCONNECTED"); break; default: break; } }
int main(void) { //Initialize pins, turn on GPIO module PIN_init(BoardGpioInitTable); //Initialize task Task_Params params; Task_Params_init(¶ms); params.priority = TASK_PRI; params.stackSize = TASK_STACK_SIZE; params.stack = taskStack; Task_construct(&taskStruct, taskFxn, ¶ms, NULL); // Construct semaphore used for pending in task Semaphore_Params sParams; Semaphore_Params_init(&sParams); sParams.mode = Semaphore_Mode_BINARY; Semaphore_construct(&sem, 0, &sParams); hSem = Semaphore_handle(&sem); BIOS_start(); }
/******************************************************************************* * @fn devpkLcdOpen * * @brief Initialize the LCD * * @descr Initializes the pins used by the LCD, creates resource access * protection semaphore, turns on the LCD device, initializes the * frame buffer, initializes to white background/dark foreground, * and finally clears the display. * * @return true if success */ bool devpkLcdOpen(void) { hLcdPin = PIN_open(&pinState, BoardDevpackLCDPinTable); if (hLcdPin != 0) { display.bg = ClrBlack; display.fg = ClrWhite; // Open the SPI driver bspSpiOpen(); // Exclusive access Semaphore_Params_init(&semParamsLCD); semParamsLCD.mode = Semaphore_Mode_BINARY; Semaphore_construct(&semLCD, 1, &semParamsLCD); hSemLCD = Semaphore_handle(&semLCD); // Turn on the display PIN_setOutputValue(hLcdPin,Board_DEVPK_LCD_DISP,1); // Graphics library init GrContextInit(&g_sContext, &g_sharp96x96LCD); // Graphics properties GrContextForegroundSet(&g_sContext, display.fg); GrContextBackgroundSet(&g_sContext, display.bg); GrContextFontSet(&g_sContext, &g_sFontFixed6x8); // Clear display GrClearDisplay(&g_sContext); GrFlush(&g_sContext); } return hLcdPin != 0; }
Int SystemCfg_create(const SystemCfg_Params *params, SystemCfg_Handle *handleP) { Int status, bufSize; Error_Block eb; SystemCfg_Object * obj; Semaphore_Params semParams; Log_print0(Diags_ENTRY, "--> "FXNN": ()"); /* initialize local vars */ status = 0; Error_init(&eb); *handleP = (SystemCfg_Handle)NULL; /* allocate the object */ obj = (SystemCfg_Handle)xdc_runtime_Memory_calloc(NULL, sizeof(SystemCfg_Object), sizeof(Int), &eb); if (obj == NULL) { Log_error1(FXNN": out of memory: size=%u", sizeof(SystemCfg_Object)); status = SystemCfg_E_NOMEMORY; goto leave; } /* object-specific initialization */ obj->remoteProcName = NULL; obj->remoteProcId = MultiProc_INVALIDID; obj->semH = NULL; obj->rcmHeapH = NULL; /* initialize structures to zero */ memset((Void *)&obj->semObj, 0, sizeof(Semaphore_Struct)); /* store the remote processor name */ bufSize = strlen(params->remoteProcName) + 1; obj->remoteProcName = (String)xdc_runtime_Memory_calloc(NULL, bufSize, sizeof(String), &eb); if (obj == NULL) { Log_error1(FXNN": out of memory: size=%u", bufSize); status = SystemCfg_E_NOMEMORY; goto leave; } strcpy(obj->remoteProcName, params->remoteProcName); /* lookup the remote processor id */ obj->remoteProcId = MultiProc_getId(obj->remoteProcName); /* create sync object used for synchronizing with remote core */ Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_COUNTING; Semaphore_construct(&obj->semObj, 0, &semParams); obj->semH = Semaphore_handle(&obj->semObj); /* add object to module list for register hook */ List_putHead(Mod_objList, &obj->link); /* success, return opaque pointer */ *handleP = (SystemCfg_Handle)obj; leave: Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
/* * ======== Server_setup ======== * * 1. create semaphore object * 2. register notify callback * 3. wait until remote core has also registered notify callback * 4. create local & shared resources * 5. send resource ready event * 6. wait for remote resource ready event * 7. open remote resources * 8. handshake the ready event */ Int Server_setup(Void) { Int status; UInt32 event; Semaphore_Params semParams; RcmServer_Params rcmServerP; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_setup:"); /* * 1. create semaphore object */ Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_COUNTING; Semaphore_construct(&Module.semS, 0, &semParams); Module.semH = Semaphore_handle(&Module.semS); /* * 2. register notify callback */ status = Notify_registerEventSingle(Module.hostProcId, Module.lineId, Module.eventId, Server_notifyCB, (UArg)&Module); if (status < 0) { goto leave; } /* * 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Task_sleep(200); /* ticks */ } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { goto leave; } /* * 4. create local & shared resources (to be opened by remote processor) */ /* * 5. send resource ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { goto leave; } /* * 6. wait for remote resource ready event */ do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_RESRDY); /* * 7. open remote resources */ /* open the rcm heap */ status = HeapBufMP_open(Global_RcmClientHeapName, &Module.heapH); if (status < 0) { Log_error1("Server_setup: HeapBufMP_open() returned error %d", (IArg)status); goto leave; } /* register the rcm heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.heapH), Global_RcmClientHeapId); if (status < 0) { Log_error1("Server_setup: MessageQ_restierHeap() returned error %d", (IArg)status); goto leave; } /* initialize RcmServer create params */ RcmServer_Params_init(&rcmServerP); rcmServerP.fxns.length = Server_fxnTab.length; rcmServerP.fxns.elem = Server_fxnTab.elem; /* create the RcmServer instance */ status = RcmServer_create(Global_RcmServerName, &rcmServerP, &Module.rcmServerH); if (status < 0) { Log_error1("Server_setup: RcmServer_create() returned error %d", (IArg)status); goto leave; } /* start the server */ RcmServer_start(Module.rcmServerH); /* * 8. handshake the ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { goto leave; } do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_READY); leave: Log_print1(Diags_EXIT, "<-- Server_setup: %d", (IArg)status); return(status); }
/******************************************************************************* * @fn bspI2cDeselect * * @brief Allow other tasks to access the I2C driver * * @param none * * @return none */ void bspI2cDeselect(void) { // Release I2C resource Semaphore_post(Semaphore_handle(&mutex)); }
/*! * @brief Function to start a transfer from the CC26XX I2C peripheral specified * by the I2C handle. * * This function is used for both transmitting and receiving data. If the I2C * is configured in ::I2C_MODE_CALLBACK mode, it is possible to chain transactions * together and receive a callback when all transactions are done. * When active I2C transactions exist, the device might enter idle, not standby. * * @pre I2CCC26XX_open() has to be called first. * Calling context: Hwi and Swi (only if using ::I2C_MODE_CALLBACK), Task * * @param handle An I2C_Handle returned by I2C_open() * * @param transaction Pointer to a I2C transaction object * * @return TRUE on successful transfer. * FALSE on an error, such as a I2C bus fault. * * @note The generic I2C API should be used when accessing the I2CCC26XX. * * @sa I2CCC26XX_open(), I2C_transfer() */ bool I2CCC26XX_transfer(I2C_Handle handle, I2C_Transaction *transaction) { bool ret = false; UInt key; I2CCC26XX_Object *object; I2CCC26XX_HWAttrs const *hwAttrs; /* Get the pointer to the object and hwAttrs */ object = handle->object; hwAttrs = handle->hwAttrs; /* Check if anything needs to be written or read */ if ((!transaction->writeCount) && (!transaction->readCount)) { /* Nothing to write or read */ return (ret); } if (object->transferMode == I2C_MODE_CALLBACK) { /* Check if a transfer is in progress */ key = Hwi_disable(); if (object->headPtr) { /* Transfer in progress */ /* * Update the message pointed by the tailPtr to point to the next * message in the queue */ object->tailPtr->nextPtr = transaction; /* Update the tailPtr to point to the last message */ object->tailPtr = transaction; /* I2C is still being used */ Hwi_restore(key); return (true); } else { /* Store the headPtr indicating I2C is in use */ object->headPtr = transaction; object->tailPtr = transaction; } Hwi_restore(key); } /* Set standby disallow constraint. */ threadSafeStdbyDisSet(); /* Acquire the lock for this particular I2C handle */ Semaphore_pend(Semaphore_handle(&(object->mutex)), BIOS_WAIT_FOREVER); /* * I2CCC26XX_primeTransfer is a longer process and * protection is needed from the I2C interrupt */ Hwi_disableInterrupt(hwAttrs->intNum); I2CCC26XX_primeTransfer(handle, transaction); Hwi_enableInterrupt(hwAttrs->intNum); if (object->transferMode == I2C_MODE_BLOCKING) { Log_print1(Diags_USER1, "I2C:(%p) Pending on transferComplete semaphore", hwAttrs->baseAddr); /* * Wait for the transfer to complete here. * It's OK to block from here because the I2C's Hwi will unblock * upon errors */ Semaphore_pend(Semaphore_handle(&(object->transferComplete)), BIOS_WAIT_FOREVER); /* Release standby disallow constraint. */ threadSafeStdbyDisRelease(); Log_print1(Diags_USER1, "I2C:(%p) Transaction completed", hwAttrs->baseAddr); /* Hwi handle has posted a 'transferComplete' check for Errors */ if (object->mode == I2CCC26XX_IDLE_MODE) { Log_print1(Diags_USER1, "I2C:(%p) Transfer OK", hwAttrs->baseAddr); ret = true; } } else { /* Always return true if in Asynchronous mode */ ret = true; } /* Release the lock for this particular I2C handle */ Semaphore_post(Semaphore_handle(&(object->mutex))); /* Return status */ return (ret); }
/* * ======== main ======== */ Void main() { PIN_init(BoardGpioInitTable); //enable iCache prefetching VIMSConfigure(VIMS_BASE, TRUE, TRUE); // Enable cache VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED); #ifndef POWER_SAVING /* Set constraints for Standby, powerdown and idle mode */ Power_setConstraint(Power_SB_DISALLOW); Power_setConstraint(Power_IDLE_PD_DISALLOW); #endif // POWER_SAVING //Initialize task Task_Params params; Task_Params_init(¶ms); params.priority = TASK_PRI; params.stackSize = TASK_STACK_SIZE; params.stack = taskStack; //semaphore init Semaphore_Params sParams; Semaphore_Params_init(&sParams); sParams.mode = Semaphore_Mode_BINARY; /* Initialize ICall module */ ICall_init(); /* Start tasks of external images - Priority 5 */ ICall_createRemoteTasks(); /* Kick off profile - Priority 3 */ GAPRole_createTask(); SimpleBLEPeripheral_createTask(); //Contruct task Task_construct(&taskStruct, taskFxn, ¶ms, NULL); // Construct semaphore used for pending in task ADC Semaphore_construct(&sem, 0, &sParams); hSem = Semaphore_handle(&sem); #ifdef FEATURE_OAD_BIM { uint8_t counter; uint32_t *vectorTable = (uint32_t*) 0x20000000; uint32_t *flashVectors = &__vector_table; // Write image specific interrupt vectors into RAM vector table. for(counter = 0; counter < 15; ++counter) { *vectorTable++ = *flashVectors++; } } #endif //FEATURE_OAD_BIM /* enable interrupts and start SYS/BIOS */ BIOS_start(); }
/*! * @brief Function for transferring using the SPI interface. * * The function will enable the SPI and UDMA modules and disallow * the device from going into standby. * * In ::SPI_MODE_BLOCKING, SPI_transfer will block task execution until the transfer * has ended. * * In ::SPI_MODE_CALLBACK, SPI_transfer does not block task execution, but calls a * callback function specified by transferCallback when the transfer has ended. * * @pre SPICC26XXDMA_open() has to be called first. * Calling context: Hwi and Swi (only if using ::SPI_MODE_CALLBACK), Task * * @param handle A SPI handle returned from SPICC26XXDMA_open() * * @param *transaction Pointer to transaction struct * * @return True if transfer is successful and false if not * * @sa SPICC26XXDMA_open(), SPICC26XXDMA_transferCancel() */ bool SPICC26XXDMA_transfer(SPI_Handle handle, SPI_Transaction *transaction) { unsigned int key; SPICC26XX_Object *object; SPICC26XX_HWAttrs const *hwAttrs; /* Get the pointer to the object and hwAttr*/ object = handle->object; hwAttrs = handle->hwAttrs; /* This is a limitation by the uDMA controller */ Assert_isTrue(transaction->count <= 1024, NULL); if (transaction->count == 0) { return (false); } /* Make sure that the buffers are aligned properly */ if (object->frameSize == SPICC26XXDMA_16bit) { Assert_isTrue(!((unsigned long)transaction->txBuf & 0x1), NULL); Assert_isTrue(!((unsigned long)transaction->rxBuf & 0x1), NULL); } /* Disable preemption while checking if a transfer is in progress */ key = Hwi_disable(); if (object->currentTransaction) { Hwi_restore(key); Log_error1("SPI:(%p) transaction still in progress", ((SPICC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); /* Flag that the transfer failed to start */ transaction->status = SPI_TRANSFER_FAILED; /* Transfer is in progress */ return (false); } /* Make sure to flag that a transaction is now active */ transaction->status = SPI_TRANSFER_STARTED; object->currentTransaction = transaction; Hwi_restore(key); /* In slave mode, optionally enable callback on CSN de-assert */ if (object->returnPartial) { PIN_setInterrupt(object->pinHandle, object->csnPin | PIN_IRQ_POSEDGE); } /* Enable the SPI module */ SSIEnable(hwAttrs->baseAddr); /* Setup DMA transfer. */ SPICC26XXDMA_configDMA(handle, transaction); /* Enable the RX overrun interrupt in the SSI module */ SSIIntEnable(hwAttrs->baseAddr, SSI_RXOR); /* Set constraints to guarantee transaction */ threadSafeConstraintSet((uint32_t)(transaction->txBuf)); if (object->transferMode == SPI_MODE_BLOCKING) { Log_print1(Diags_USER1, "SPI:(%p) transfer pending on transferComplete " "semaphore", ((SPICC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); if (!Semaphore_pend(Semaphore_handle(&(object->transferComplete)), object->transferTimeout)) { /* Cancel the transfer, if we experience a timeout */ SPICC26XXDMA_transferCancel(handle); /* * SPICC26XXDMA_transferCancel peforms a callback which posts a * transferComplete semaphore. This call consumes this extra post. */ Semaphore_pend(Semaphore_handle(&(object->transferComplete)), BIOS_NO_WAIT); return (false); } } return (true); }