/********************************************************************* * @fn osal_start_system * * @brief * * This function is the main loop function of the task system. It * will look through all task events and call the task_event_processor() * function for the task with the event. If there are no events (for * all tasks), this function puts the processor into Sleep. * This Function doesn't return. * * @param void * * @return none */ void osal_start_system( void ) { uint16 events; uint16 retEvents; while(1) { TaskActive = osalNextActiveTask(); if ( TaskActive ) { HAL_ENTER_CRITICAL_SECTION(); events = TaskActive->events; // Clear the Events for this task TaskActive->events = 0; HAL_EXIT_CRITICAL_SECTION(); if ( events != 0 ) { // Call the task to process the event(s) if ( TaskActive->pfnEventProcessor ) { retEvents = (TaskActive->pfnEventProcessor)( TaskActive->taskID, events ); // Add back unprocessed events to the current task HAL_ENTER_CRITICAL_SECTION(); TaskActive->events |= retEvents; HAL_EXIT_CRITICAL_SECTION(); } } } } }
/************************************************************************************************** * @fn macBackoffTimerCount * * @brief Returns the current backoff count. * * @param none * * @return current backoff count ************************************************************************************************** */ uint32 macBackoffTimerCount(void) { halIntState_t s; uint32 backoffCount; HAL_ENTER_CRITICAL_SECTION(s); backoffCount = MAC_RADIO_BACKOFF_COUNT(); HAL_EXIT_CRITICAL_SECTION(s); #ifdef MAC_RADIO_FEATURE_HARDWARE_OVERFLOW_NO_ROLLOVER /* * Extra processing is required if the radio has a special hardware overflow * count feature. Unfortunately this feature does not provide for setting a * rollover value. This must be done manually. * * This means there is a small window in time when reading the hardware count * will be inaccurate. It's possible it could be one more than the allowable * count. This happens if the count has just incremented beyond the maximum * and is queried before the ISR has a chance to run and reset the backoff * count back to zero. (Pure software implementation of backoff count does * not have this problem.) * * To solve this, before returning a value for the backoff count, the value * must be tested to see if it is beyond the maximum value. If so, a rollover * interrupt that will set backoff count to zero is imminent. In that case, * the correct backoff count of zero is returned. */ if (backoffCount >= backoffTimerRollover) { return(0); } #endif return(backoffCount); }
/************************************************************************************************** * @fn macBackoffTimerCancelTrigger * * @brief Cancels the trigger for the backoff counter - obselete for CC253x and CC26xx. * For CC253x and CC26xx, the timer trigger should never be late, therefore, no * need to cancel. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerCancelTrigger(void) { MAC_RADIO_BACKOFF_COMPARE_CLEAR_INTERRUPT(); #if defined USE_ICALL || defined OSAL_PORT2TIRTOS /* backoffTimerTrigger must be set to a value * to properly use rollover value for the next wakeup time. */ { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); /* This code assumes that backoff timer callback does not cause * a problem when the callback is made at the rollover even if * no timer is associated with it. At the time the following * code is written, mac_timer.c can live with such a callback. * Setting backoff comparator value one greater than rollver value * might be conceived here to lift the above constraint, * but it would have to ensure that rollover value is never * the highest counter value, which is a more dangerous assumption. */ backoffTimerTrigger = macBackoffTimerRollover; /* Note that MAC_RADIO_BACKOFF_COMPARE_CLEAR_INTERRUPT() is not implemented * correctly and hence backoff timer trigger interrupt can still occur. * Instead of fixing MAC_RADIO_BACKOFF_COMPARE_CLEAR_INTERRUPT() macro, * comparator is set again, to simplify interrupt handling. */ MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerTrigger); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(intState); } #endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */ }
/************************************************************************************************** * @fn macBackoffTimerPeriodIsr * * @brief Interrupt service routine that fires when the backoff count rolls over on * overflow period. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerPeriodIsr(void) { halIntState_t s; uint32 macRatCount = MAC_RAT_COUNT; uint32 backoffRolloverRat = macBackoffTimerRollover * MAC_BACKOFF_TO_RAT_RATIO; uint32 ratCompensation = (macRatCount - macPrevPeriodRatCount) % MAC_BACKOFF_TO_RAT_RATIO; MAC_ASSERT( macBackoffTimerRollover <= MAC_BACKOFF_MAXIMUM_ROLLOVER ); if (macRatCount < backoffRolloverRat) { /* RAT wraparound has occurred. This would occur once in a blue moon (1073.74 seconds). */ DBG_PRINTL1(DBGSYS, "!!! RAT wraparound !!! RAT = %u", macRatCount); } DBG_PRINTL2(DBGSYS, "macRatChanA Period ISR, Rollover Period = %u, RAT Compensation = %u", macBackoffTimerRollover, ratCompensation); /* Convert count to RAT count and set MAC Channel A Compare. The modulus calculation will * compensate the math or interrupt latency error and prevent it from being accumulated. * Note that MAC_BACKOFF_TO_RAT_RATIO is used as part of compensation. This means the * maximum error that can be compensated is 320us. If the interrupt latency is greater * than 320us, more elaborated compensation scheme must be used for Beacon mode. * Non-beacon mode does not require absolute timing. Longer interrupt latency can be * tolerated. */ macPrevPeriodRatCount = macRatCount - ratCompensation; macSetupRATChanCompare( macRatChanA, backoffRolloverRat + macPrevPeriodRatCount ); macBackoffTimerRolloverCallback(); HAL_ENTER_CRITICAL_SECTION(s); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); }
/*********************************************************************************** * @fn halUartPollRx * * @brief Poll for data from USB. * * @param none * * @return none */ void halUartPollRx(void) { uint8 cnt; uint8 ep = USBFW_GET_SELECTED_ENDPOINT(); USBFW_SELECT_ENDPOINT(4); /* If the OUT endpoint has received a complete packet. */ if (USBFW_OUT_ENDPOINT_DISARMED()) { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); /* Get length of USB packet, this operation must not be interrupted. */ cnt = USBFW_GET_OUT_ENDPOINT_COUNT_LOW(); cnt += USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() >> 8; HAL_EXIT_CRITICAL_SECTION(intState); while (cnt--) { halUartRxQ[halUartRxT++] = HWREG(USB_F4); } USBFW_ARM_OUT_ENDPOINT(); /* If the USB has transferred in more Rx bytes, reset the Rx idle timer. */ /* Re-sync the shadow on any 1st byte(s) received. */ if (rxTick == 0) { rxShdw = ST0; } rxTick = HAL_UART_USB_IDLE; } else if (rxTick)
/********************************************************************* * @fn osal_run_task * * @brief * * This function is the main loop function of the task system. It * will look through all task events and call the task_event_processor() * function for the task with the event. If there are no events (for * all tasks), this function puts the processor into Sleep. * This Function doesn't return. * * @param void * * @return none */ static void osal_run_task(uint8 idx) { uint16 events; halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); events = tasksEvents[idx]; tasksEvents[idx] = 0; // Clear the Events for this task. HAL_EXIT_CRITICAL_SECTION(intState); events = (tasksArr[idx])( idx, events ); HAL_ENTER_CRITICAL_SECTION(intState); tasksEvents[idx] |= events; // Add back unprocessed events to the current task. HAL_EXIT_CRITICAL_SECTION(intState); }
/************************************************************************************************** * @fn HalFlashRead * * @brief This function reads 'cnt' bytes from the internal flash. * * input parameters * * @param pg - A valid flash page number. * @param offset - A valid offset into the page. * @param buf - A valid buffer space at least as big as the 'cnt' parameter. * @param cnt - A valid number of bytes to read. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt) { // Calculate the offset into the containing flash bank as it gets mapped into XDATA. uint8 *pData = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) + ((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE); uint8 memctr = MEMCTR; // Save to restore. #if (!defined HAL_OAD_BOOT_CODE) && (!defined HAL_OTA_BOOT_CODE) halIntState_t is; #endif pg /= HAL_FLASH_PAGE_PER_BANK; // Calculate the flash bank from the flash page. #if (!defined HAL_OAD_BOOT_CODE) && (!defined HAL_OTA_BOOT_CODE) HAL_ENTER_CRITICAL_SECTION(is); #endif // Calculate and map the containing flash bank into XDATA. MEMCTR = (MEMCTR & 0xF8) | pg; while (cnt--) { *buf++ = *pData++; } MEMCTR = memctr; #if (!defined HAL_OAD_BOOT_CODE) && (!defined HAL_OTA_BOOT_CODE) HAL_EXIT_CRITICAL_SECTION(is); #endif }
/************************************************************************************************** * @fn macBackoffTimerCompareIsr * * @brief Interrupt service routine that fires when the backoff count is equal * to the trigger count. * * @param none * * @return none ************************************************************************************************** */ void macBackoffTimerCompareIsr(void) { uint8 oldState; halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); oldState = compareState; /* if compare is a rollover, set count to zero */ if (oldState & COMPARE_STATE_ROLLOVER_BV) { MAC_RADIO_BACKOFF_SET_COUNT(0); macBackoffTimerRolloverCallback(); } /* if compare is a trigger, reset for rollover and run the trigger callback */ if (oldState & COMPARE_STATE_TRIGGER_BV) { compareState = COMPARE_STATE_ROLLOVER; MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover); HAL_EXIT_CRITICAL_SECTION(s); macBackoffTimerTriggerCallback(); } else if (oldState == COMPARE_STATE_ROLLOVER_AND_ARM_TRIGGER) { compareState = COMPARE_STATE_TRIGGER; MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerTrigger); HAL_EXIT_CRITICAL_SECTION(s); } else { HAL_EXIT_CRITICAL_SECTION(s); } }
/********************************************************************* * @fn HalSPIRead * * @brief Read from the external NV storage via SPI. * * @param addr - Offset into the external NV. * @param pBuf - Pointer to the buffer in which to copy the bytes read from external NV. * @param len - Number of bytes to read from external NV. * * @return None. *********************************************************************/ static void HalSPIRead(uint32 addr, uint8 *pBuf, uint16 len) { #if !HAL_OAD_BOOT_CODE uint8 shdw = P1DIR; halIntState_t his; HAL_ENTER_CRITICAL_SECTION(his); P1DIR |= BV(3); #endif XNV_SPI_BEGIN(); do { xnvSPIWrite(XNV_STAT_CMD); } while (XNV_SPI_RX() & XNV_STAT_WIP); XNV_SPI_END(); asm("NOP"); asm("NOP"); XNV_SPI_BEGIN(); xnvSPIWrite(XNV_READ_CMD); xnvSPIWrite(addr >> 16); xnvSPIWrite(addr >> 8); xnvSPIWrite(addr); xnvSPIWrite(0); while (len--) { xnvSPIWrite(0); *pBuf++ = XNV_SPI_RX(); } XNV_SPI_END(); #if !HAL_OAD_BOOT_CODE P1DIR = shdw; HAL_EXIT_CRITICAL_SECTION(his); #endif }
/************************************************************************************************** * @fn macRxOff * * @brief Turn off the receiver if it's not already off. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxOff(void) { halIntState_t s; DBG_PRINT1(DBGSYS, "macRxOff(): macRxOnFlag = 0x%X", macRxOnFlag); HAL_ENTER_CRITICAL_SECTION(s); if (macRxOnFlag) { macRxOnFlag = 0; DBG_PRINT0(DBGSYS, "MAC_RADIO_RXTX_OFF()"); MAC_RADIO_RXTX_OFF(); /* Wait till RX is completely off before issuing another RX related * command which may fail if issued beforehand. */ macCheckCommnadDone(&macRxEdScan.rxCmd.rfOpCmd); /* Wait till all FG commands are done */ macCheckCommnadDone(&macCsmaCaCmd.rfOpCmd); macCheckCommnadDone(&macTxCmd.rfOpCmd); macCheckCommnadDone(&macRxAckCmd.rfOpCmd); MAC_DEBUG_TURN_OFF_RX_LED(); /* just in case a receive was about to start, flush the receive FIFO */ MAC_RADIO_FLUSH_RX_FIFO(); /* clear any receive interrupt that happened to squeak through */ MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG(); } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRadioUpdateTxPower * * @brief Update the radio's transmit power if a new power level has been requested * * @param reqTxPower - file scope variable that holds the last request power level * macPhyTxPower - global variable that holds radio's set power level * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRadioUpdateTxPower(void) { halIntState_t s; /* * If the requested power setting is different from the actual radio setting, * attempt to udpate to the new power setting. */ HAL_ENTER_CRITICAL_SECTION(s); if (reqTxPower != macPhyTxPower) { /* * Radio power cannot be updated when the radio is physically transmitting. * If there is a possibility radio is transmitting, do not change the power * setting. This function will be called again after the current transmit * completes. */ if (!macRxOutgoingAckFlag && !MAC_TX_IS_PHYSICALLY_ACTIVE()) { /* * Set new power level; update the shadow value and write * the new value to the radio hardware. */ macPhyTxPower = reqTxPower; MAC_RADIO_SET_TX_POWER(macPhyTxPower); } } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRadioUpdateChannel * * @brief Update the radio channel if a new channel has been requested. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRadioUpdateChannel(void) { halIntState_t s; MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */ /* if the channel has changed, set the radio to the new channel */ HAL_ENTER_CRITICAL_SECTION(s); if (reqChannel != macPhyChannel) { macPhyChannel = reqChannel; HAL_EXIT_CRITICAL_SECTION(s); /* changing the channel stops any receive in progress */ macRxOff(); MAC_RADIO_SET_CHANNEL(macPhyChannel); /* If the channel is updated in the middle of receiving a frame, we must * clean up the Rx logic. */ macRxHaltCleanup(); macRxOnRequest(); } else { HAL_EXIT_CRITICAL_SECTION(s); } }
/************************************************************************************************** * @fn MAC_MlmeSetActivePib * * @brief This function initializes the PIB. * * input parameters * * @param None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void MAC_MlmeSetActivePib( void* pPib ) { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); pMacPib = (macPib_t *)pPib; HAL_EXIT_CRITICAL_SECTION(intState); }
/************************************************************************************************** * @fn macMcuPrecisionCount * * @brief This function is used by higher layer to read a free running counter driven by * MAC timer. * * @param none * * @return overflowCount ************************************************************************************************** */ uint32 macMcuPrecisionCount(void) { uint32 overflowCount = 0; halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); /* This T2 access macro allows accessing both T2MOVFx and T2Mx */ MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE(); /* Latch the entire T2MOVFx first by reading T2M0. * T2M0 is discarded. */ T2M0; ((uint8 *)&overflowCount)[UINT32_NDX0] = T2MOVF0; ((uint8 *)&overflowCount)[UINT32_NDX1] = T2MOVF1; ((uint8 *)&overflowCount)[UINT32_NDX2] = T2MOVF2; /* the overflowCount needs to account for the accumulated overflow count in Beacon mode. */ overflowCount += accumulatedOverflowCount; HAL_EXIT_CRITICAL_SECTION(s); return(overflowCount); }
/********************************************************************* * @fn osal_pwrmgr_powerconserve * * @brief This function is called from the main OSAL loop when there are * no events scheduled and shouldn't be called from anywhere else. * * @param none. * * @return none. */ void osal_pwrmgr_powerconserve( void ) { uint32 next; halIntState_t intState; // Should we even look into power conservation #ifdef USER_DEFINED if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON && !E009_upoff && isPair ) #else if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON ) #endif { // Are all tasks in agreement to conserve if ( pwrmgr_attribute.pwrmgr_task_state == 0 ) { // Hold off interrupts. HAL_ENTER_CRITICAL_SECTION( intState ); // Get next time-out next = osal_next_timeout(); // Re-enable interrupts. HAL_EXIT_CRITICAL_SECTION( intState ); // Put the processor into sleep mode OSAL_SET_CPU_INTO_SLEEP( next ); } } }
/************************************************************************************************** * @fn macBackoffTimerPwrNotify * * @brief power state transition notify callback function * * @param eventType transition event type * @param data not used * * @return Power_NOTIFYDONE ************************************************************************************************** */ static Power_NotifyResponse macBackoffTimerPwrNotify(Power_Event eventType, UArg data) { if (eventType == Power_AWAKE_STANDBY) { /* Wakeup must be handled from the thread context. * Signal the event to the OSAL thread. */ halIntState_t is; HAL_ENTER_CRITICAL_SECTION(is); macBackoffTimerEvents |= MAC_BACKOFF_TIMER_EVENT_POWER_WAKEUP; HAL_EXIT_CRITICAL_SECTION(is); osal_set_event(macTaskId, 0); } else if (eventType == Power_ENTERING_STANDBY) { /* Stop RAT timer */ macRATValue = macStopRAT(); /* Park CM0 */ MAC_RADIO_POWER_DOWN(); Hwi_disableInterrupt( INT_RF_CPE0 ); Hwi_disableInterrupt( INT_RF_CPE1 ); Hwi_disableInterrupt( INT_RF_HW ); Hwi_disableInterrupt( INT_RF_CMD_ACK ); } else if (eventType == Power_ENTERING_SHUTDOWN) { /* Park CM0 */ MAC_RADIO_POWER_DOWN(); } return Power_NOTIFYDONE; }
/************************************************************************************************** * @fn macBackoffTimerSetTrigger * * @brief Sets the trigger count for the backoff counter. A callback is exectuted when * the backoff count reaches the trigger * * @param triggerBackoff - backoff count for new trigger * * @return none ************************************************************************************************** */ void macBackoffTimerSetTrigger(uint32 triggerBackoff) { halIntState_t s; MAC_ASSERT(triggerBackoff < backoffTimerRollover); /* trigger backoff must be less than rollover backoff */ HAL_ENTER_CRITICAL_SECTION(s); backoffTimerTrigger = triggerBackoff; if (triggerBackoff > MAC_RADIO_BACKOFF_COUNT()) { compareState = COMPARE_STATE_TRIGGER; MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff); } else { if (triggerBackoff == 0) { compareState = COMPARE_STATE_ROLLOVER_AND_TRIGGER; } else { compareState = COMPARE_STATE_ROLLOVER_AND_ARM_TRIGGER; } MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover); } HAL_EXIT_CRITICAL_SECTION(s); }
/****************************************************************************** * @fn HalUARTWriteDMA * * @brief Write a buffer to the UART. * * @param buf - pointer to the buffer that will be written, not freed * len - length of * * @return length of the buffer that was sent *****************************************************************************/ static uint16 HalUARTWriteDMA(uint8 *buf, uint16 len) { uint16 cnt; halIntState_t his; uint8 txSel; txIdx_t txIdx; // Enforce all or none. if ((len + dmaCfg.txIdx[dmaCfg.txSel]) > HAL_UART_DMA_TX_MAX) { return 0; } HAL_ENTER_CRITICAL_SECTION(his); txSel = dmaCfg.txSel; txIdx = dmaCfg.txIdx[txSel]; HAL_EXIT_CRITICAL_SECTION(his); for (cnt = 0; cnt < len; cnt++) { dmaCfg.txBuf[txSel][txIdx++] = buf[cnt]; } HAL_ENTER_CRITICAL_SECTION(his); if (txSel != dmaCfg.txSel) { HAL_EXIT_CRITICAL_SECTION(his); txSel = dmaCfg.txSel; txIdx = dmaCfg.txIdx[txSel]; for (cnt = 0; cnt < len; cnt++) { dmaCfg.txBuf[txSel][txIdx++] = buf[cnt]; } HAL_ENTER_CRITICAL_SECTION(his); } dmaCfg.txIdx[txSel] = txIdx; if (dmaCfg.txIdx[(txSel ^ 1)] == 0) { // TX DMA is expected to be fired dmaCfg.txDMAPending = TRUE; } HAL_EXIT_CRITICAL_SECTION(his); return cnt; }
/************************************************************************************************* * @brief Write a buffer to the UART * @param port - UART port (not used.) * pBuffer - pointer to the buffer that will be written * length - length of * @return length of the buffer that was sent *************************************************************************************************/ uint16 HalUARTOutBuf (uint8 port, uint8 *pBuffer, uint16 length) { uint16 cnt, idx; halIntState_t intState; if (!uartRecord.configured) { return 0; } // Capture the value of the volatile variables. idx = uartRecord.tx.bufferHead; cnt = uartRecord.tx.bufferTail; if (cnt == idx) { cnt = uartRecord.tx.maxBufSize; } else if (cnt > idx) { cnt = uartRecord.tx.maxBufSize - cnt + idx; } else // (cnt < idx) { cnt = idx - cnt; } // Accept "all-or-none" on write request. if (cnt < length) { return 0; } idx = uartRecord.tx.bufferTail; for (cnt = 0; cnt < length; cnt++) { uartRecord.tx.pBuffer[idx++] = pBuffer[cnt]; if (idx >= uartRecord.tx.maxBufSize) { idx = 0; } } HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts. cnt = uartRecord.tx.bufferTail; if (cnt == uartRecord.tx.bufferHead) { if (uartRecord.intEnable) { HAL_UART_TX_INT_ENABLE(); } HAL_UART_PUTBYTE(uartRecord.tx.pBuffer[uartRecord.tx.bufferHead]); // Send a char to UART. } uartRecord.tx.bufferTail = idx; HAL_EXIT_CRITICAL_SECTION(intState); // Restore interrupt enable. return length; // Return the number of bytes actually put into the buffer. }
/********************************************************************* * @fn osal_mem_free * * @brief Implementation of the de-allocator functionality. * * @param ptr - pointer to the memory to free. * * @return void */ void osal_mem_free( void *ptr ) { osalMemHdr_t *currHdr; halIntState_t intState; #if ( OSALMEM_GUARD ) // Try to protect against premature use by HAL / OSAL. if ( ready != OSALMEM_READY ) { osal_mem_init(); } #endif HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts. OSALMEM_ASSERT( ptr ); currHdr = (osalMemHdr_t *)ptr - 1; // Has this block already been freed? OSALMEM_ASSERT( *currHdr & OSALMEM_IN_USE ); *currHdr &= ~OSALMEM_IN_USE; #if ( OSALMEM_PROFILER ) { uint16 size = *currHdr; byte idx; for ( idx = 0; idx < OSALMEM_PROMAX; idx++ ) { if ( size <= proCnt[idx] ) { break; } } proCur[idx]--; } #endif #if ( OSALMEM_METRICS ) memAlo -= *currHdr; blkFree++; #endif if ( ff1 > currHdr ) { ff1 = currHdr; } #if ( OSALMEM_PROFILER ) osal_memset( (byte *)currHdr+HDRSZ, OSALMEM_REIN, (*currHdr - HDRSZ) ); #endif HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts. }
/************************************************************************************************** * @fn macBackoffTimerCancelTrigger * * @brief Cancels the trigger for the backoff counter. * * @param none * * @return none ************************************************************************************************** */ void macBackoffTimerCancelTrigger(void) { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); compareState = COMPARE_STATE_ROLLOVER; MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover); HAL_EXIT_CRITICAL_SECTION(s); }
/****************************************************************************** * @fn HalSPIWrite * * @brief Write to the external NV storage via SPI. * * @param addr - Offset into the external NV. * @param pBuf - Pointer to the buffer in from which to write bytes to external NV. * @param len - Number of bytes to write to external NV. * * @return None. *****************************************************************************/ static void HalSPIWrite(uint32 addr, uint8 *pBuf, uint16 len) { uint8 cnt; #if !HAL_OTA_BOOT_CODE uint8 shdw = P1DIR; halIntState_t his; HAL_ENTER_CRITICAL_SECTION(his); P1DIR |= BV(3); #endif while (len) { XNV_SPI_BEGIN(); do { xnvSPIWrite(XNV_STAT_CMD); } while (XNV_SPI_RX() & XNV_STAT_WIP); XNV_SPI_END(); asm("NOP"); asm("NOP"); XNV_SPI_BEGIN(); xnvSPIWrite(XNV_WREN_CMD); XNV_SPI_END(); asm("NOP"); asm("NOP"); XNV_SPI_BEGIN(); xnvSPIWrite(XNV_WRPG_CMD); xnvSPIWrite(addr >> 16); xnvSPIWrite(addr >> 8); xnvSPIWrite(addr); // Can only write within any one page boundary, so prepare for next page write if bytes remain. cnt = 0 - (uint8)addr; if (cnt) { addr += cnt; } else { addr += 256; } do { xnvSPIWrite(*pBuf++); cnt--; len--; } while (len && cnt); XNV_SPI_END(); } #if !HAL_OTA_BOOT_CODE P1DIR = shdw; HAL_EXIT_CRITICAL_SECTION(his); #endif }
/************************************************************************************************** * @fn macMcuTimerForceDelay * * @brief Delay the timer by the requested number of ticks. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macMcuTimerForceDelay(uint16 x) { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); MAC_MCU_T2_ACCESS_COUNT_VALUE(); T2M0 = (x) & 0xFF; T2M1 = (x) >> 8; HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerSetCount * * @brief Sets the count of the backoff timer. * * @param backoff - new count * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerSetCount(uint32 backoff) { halIntState_t s; MAC_ASSERT(backoff < backoffTimerRollover); /* count must be less than rollover value */ MAC_ASSERT(!(backoff & 0x80000000)); /* count must not represent negative value for int32 */ HAL_ENTER_CRITICAL_SECTION(s); MAC_RADIO_BACKOFF_SET_COUNT(backoff); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxSoftEnable * * @brief Set enable flags but don't turn on the receiver. Useful to leave the receiver * on after a transmit, but without turning it on immediately. * * @param flags - byte containing rx enable flags to set * * @return none ************************************************************************************************** */ void macRxSoftEnable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ /* set the enable flags but do not turn on the receiver */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags |= flags; HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxOnRequest * * @brief Turn on the receiver if any rx enable flag is set. * * @param none * * @return none ************************************************************************************************** */ void macRxOnRequest(void) { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); if (macRxEnableFlags) { macRxOn(); } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerSetRollover * * @brief Set rollover count of backoff timer. * * @param rolloverBackoff - backoff count where count is reset to zero * * @return none ************************************************************************************************** */ void macBackoffTimerSetRollover(uint32 rolloverBackoff) { halIntState_t s; MAC_ASSERT(rolloverBackoff > MAC_RADIO_BACKOFF_COUNT()); /* rollover value must be greater than count */ HAL_ENTER_CRITICAL_SECTION(s); backoffTimerRollover = rolloverBackoff; MAC_RADIO_BACKOFF_SET_COMPARE(rolloverBackoff); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerCount * * @brief Returns the current backoff count. * * @param none * * @return current backoff count ************************************************************************************************** */ MAC_INTERNAL_API uint32 macBackoffTimerCount(void) { halIntState_t s; uint32 backoffCount; HAL_ENTER_CRITICAL_SECTION(s); backoffCount = MAC_RADIO_BACKOFF_COUNT(); HAL_EXIT_CRITICAL_SECTION(s); return(backoffCount); }
/************************************************************************************************** * @fn halSleepSetTimer * * @brief This function sets the MSP430 MAC timer compare value. First it reads and * stores the value of the sleep timer; this value is used later to update MAC * timers. Then the timeout value is converted from 320 usec units to system clock * period units and the compare value is set to the timeout. * * input parameters * * @param timeout - Pointer to the timeout value in 320 usec units. The sleep timer compare * is set to this value. * * output parameters - none * * None. * * @return None. ************************************************************************************************** */ void halSleepSetTimer( uint32 timeout ) { halIntState_t s; uint32 ticks; HAL_ENTER_CRITICAL_SECTION(s); #ifdef __msp430x54x /* read the current MAC timer and store value for later */ ticks = halSleepTimerStart = HAL_MAC_SLEEP_TIMER_TAR(); #endif /* Switch MAC timer clock source and change prescaler * halt the timer while updating */ HAL_MAC_SLEEP_TIMER_SLOW_DOWN(); HAL_EXIT_CRITICAL_SECTION(s); #ifdef __msp430x54x /* With MSP430F5438 RTM silicon, when the counter mode is moved from 'up' * to 'stop' and the timer counter equals the capture/compare value in a * TACCRx register the transition of modes will pull the TAR bits (15:4) * to a '1' momentarily. Re-initialize TAR as a temporary workaround until * the post-RTM revisions of silicon with this bug fixed. */ HAL_MAC_SLEEP_TIMER_TAR() = halSleepTimerStart; #else /* read the current MAC timer and store value for later */ ticks = halSleepTimerStart = HAL_MAC_SLEEP_TIMER_TAR(); #endif /* read the current MAC timer compare count and store value for later */ halSleepTimerCompareStart = HAL_MAC_SLEEP_TIMER_COMPARE(); /* The MAC tick is 32KHz/8 = 4096Hz. The ratio of 4096Hz ticks * to 320 usec ticks is (320e-6)/(1/4096) = 1.31072 = 4096 / 3125. */ ticks += (timeout * 4096 / 3125); /* sleep away one chunk at a time */ if ( ticks > MAX_SLEEP_COUNT ) { /* adjust timeout for the next sleep cycle */ ticks = MAX_SLEEP_COUNT; } /* set MAC timer compare */ HAL_MAC_SLEEP_TIMER_SET_COMPARE(((uint16)ticks)); /* restart the timer */ HAL_MAC_SLEEP_TIMER_RESTART(); }
/************************************************************************************************** * @fn macBackoffTimerCompareIsr * * @brief Interrupt service routine that fires when the backoff count is equal * to the trigger count. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerCompareIsr(void) { halIntState_t s; DBG_PRINT1(DBGSYS, "macRatChanB Compare ISR, Backoff RAT count = %u", MAC_RADIO_BACKOFF_COUNT()); macBackoffTimerTriggerCallback(); HAL_ENTER_CRITICAL_SECTION(s); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); }