From b24866225a6301d3a663f874725e83c012dc25d3 Mon Sep 17 00:00:00 2001 From: Florent Duchon Date: Wed, 26 Dec 2012 17:36:00 +0100 Subject: digital/beacon: add bitcloud stack into common directory digital/zigbit --- .../stack/Components/HAL/avr/common/src/adc.c | 133 +++ .../stack/Components/HAL/avr/common/src/appTimer.c | 169 ++++ .../stack/Components/HAL/avr/common/src/eeprom.c | 156 +++ .../Components/HAL/avr/common/src/halTaskManager.c | 305 ++++++ .../Components/HAL/avr/common/src/i2cPacket.c | 371 +++++++ .../stack/Components/HAL/avr/common/src/irq.c | 143 +++ .../stack/Components/HAL/avr/common/src/pwm.c | 165 +++ .../Components/HAL/avr/common/src/resetReason.c | 59 ++ .../stack/Components/HAL/avr/common/src/sleep.c | 79 ++ .../Components/HAL/avr/common/src/sleepTimer.c | 126 +++ .../stack/Components/HAL/avr/common/src/spi.c | 602 +++++++++++ .../stack/Components/HAL/avr/common/src/timer.c | 114 +++ .../stack/Components/HAL/avr/common/src/usart.c | 1061 ++++++++++++++++++++ .../stack/Components/HAL/avr/common/src/usb.c | 435 ++++++++ .../stack/Components/HAL/avr/common/src/w1.c | 382 +++++++ 15 files changed, 4300 insertions(+) create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/adc.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/appTimer.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/eeprom.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/halTaskManager.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/irq.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/pwm.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/resetReason.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleep.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleepTimer.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/spi.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/timer.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usb.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/w1.c (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/avr/common') diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/adc.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/adc.c new file mode 100644 index 00000000..03598dcd --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/adc.c @@ -0,0 +1,133 @@ +/**************************************************************************//** + \file adc.c + + \brief Implementation of ADC interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + Types section +******************************************************************************/ +typedef enum +{ + IDLE, // idle + DATA, // performs request + BUSY // the module is ready to start conversion +} AdcStates_t; + +typedef struct +{ + void (*callback)(void); // address of callback +} HalAdcControl_t; + +/****************************************************************************** + Global variables section +******************************************************************************/ +AdcStates_t halAdcState = IDLE; // Monitors current state +HalAdcControl_t halAdcControl; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Opens the ADC to make the measuring on a ADC channel. +Parameters: + param - pointer to parameter structure +Returns: + -1 - unsupported parameter or ADC is busy. + 0 - on success. +******************************************************************************/ +int HAL_OpenAdc(HAL_AdcParams_t *param) +{ + if (IDLE != halAdcState) + return -1; + if (NULL == param) + return -1; + if (NULL == param->bufferPointer) + return -1; + if (param->resolution > RESOLUTION_10_BIT) + return -1; + /* unsupported voltage reference */ + if (param->voltageReference & 0x3F) + return -1; + /* adc speed must be only 9600 or 4800 SPS for 10 bit resolution */ + if ((RESOLUTION_10_BIT == param->resolution) && (param->sampleRate < ADC_9600SPS)) + return -1; + + halAdcState = BUSY; + halOpenAdc(param); + halAdcControl.callback = param->callback; + return 0; +} + +/****************************************************************************** +Starts ADC with the parameters that were defined at HAL_OpenAdc. +Parameters: + channel - number of channel +Returns: + -1 - the ADC was not opened, unsupported channel number. + 0 - on success. +******************************************************************************/ +int HAL_ReadAdc(HAL_AdcChannelNumber_t channel) +{ + if (BUSY != halAdcState) + return -1; + if (((channel > HAL_ADC_CHANNEL3) && (channel < HAL_ADC_DIFF_CHANNEL0)) || (channel > HAL_ADC_DIFF_CHANNEL7)) + return -1; + + halAdcState = DATA; + halStartAdc(channel); + return 0; +} + +/****************************************************************************** +Closes the ADC. +Parameters: + none. +Returns: + -1 - the module was not opened to be used. + 0 - on success. +******************************************************************************/ +int HAL_CloseAdc(void) +{ + if (IDLE == halAdcState) + return -1; + + halAdcState = IDLE; + halCloseAdc(); + return 0; +} + +/****************************************************************************** + ADC interrupt handler. +******************************************************************************/ +void halSigAdcHandler(void) +{ + if (DATA == halAdcState) + { + halAdcState = BUSY; + if (NULL != halAdcControl.callback) + halAdcControl.callback(); + } +} +// eof adc.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/appTimer.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/appTimer.c new file mode 100644 index 00000000..45047822 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/appTimer.c @@ -0,0 +1,169 @@ +/**************************************************************************//** + \file appTimer.c + + \brief Implementation of appTimer. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#if defined(_SYSTEM_TIME_ON_SLEEP_TIMER_) + #include +#endif + +/****************************************************************************** + External global variables section +******************************************************************************/ +extern uint8_t halSleepTimerOvfw; +extern uint8_t halAppTimeOvfw; + +/****************************************************************************** + Global variables section +******************************************************************************/ +static HAL_AppTimer_t *halAppTimerHead = NULL; // head of appTimer list + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Interrupt handler of appTimer clock. +******************************************************************************/ +void halAppTimerHandler(void) +{ + uint32_t sysTime; + + // search for expired timers and call their callbacks + while ( halAppTimerHead + && ((sysTime = halGetTimeOfAppTimer()) - halAppTimerHead->service.sysTimeLabel) >= halAppTimerHead->interval) + { + HAL_AppTimer_t *p = halAppTimerHead; + halRemoveTimer(&halAppTimerHead, NULL, p); + if (TIMER_REPEAT_MODE == p->mode) + { + p->service.sysTimeLabel = sysTime; + halAddTimer(&halAppTimerHead, p, sysTime); + } + p->callback(); + } +} + +/****************************************************************************** +Check if timer is already started. +Parameters: + appTimer - pointer to HAL_AppTimer_t. +Returns: + true - timer specified already started and presents in the system timers queue + false - timer is't started yet +******************************************************************************/ +static bool isTimerAlreadyStarted(HAL_AppTimer_t *appTimer) +{ + bool result = false; + Timer_t *p; // p is bottom of list + p = halAppTimerHead; + + while (NULL != p) + { + if (p == appTimer) + { + result = true; + assert(false, APPTIMER_MISTAKE); + break; + } + p = (Timer_t *)p->service.next; + } + return result; +} + + +/****************************************************************************** +Starts to count an interval. +Parameters: + appTimer - pointer to HAL_AppTimer_t. +Returns: + -1 - pointer is NULL. + 0 - success +******************************************************************************/ +int HAL_StartAppTimer(HAL_AppTimer_t *appTimer) +{ + uint32_t sysTime; + + if (!appTimer) + return -1; + + if (true == isTimerAlreadyStarted(appTimer)) + return 0; + + sysTime = halGetTimeOfAppTimer(); + appTimer->service.next = NULL; + appTimer->service.sysTimeLabel = sysTime; + halAddTimer((Timer_t**)(&halAppTimerHead), (Timer_t*)appTimer, sysTime); + return 0; +} + +/****************************************************************************** +Stops the timer. +Parameters: + appTimer - pointer to HAL_AppTimer_t. +Returns: + -1 there is not the appTimer. + 0 - success +******************************************************************************/ +int HAL_StopAppTimer(HAL_AppTimer_t *appTimer) +{ + Timer_t *prev = 0; + Timer_t **t = &appTimer; + + if (!appTimer) + return -1; + if (halAppTimerHead != *t) + { + if (!(prev = halFindPrevTimer((Timer_t**)(&halAppTimerHead), appTimer))) + return -1; // This timer is not in the list + } + halRemoveTimer((Timer_t**)(&halAppTimerHead), prev, appTimer); + return 0; +} + +/**************************************************************************//** +\brief Gets system time. + +\return + time since power up in milliseconds(8 bytes). +******************************************************************************/ +BcTime_t HAL_GetSystemTime(void) +{ + BcTime_t sysTime = 0ull; + + #if defined(_SYSTEM_TIME_ON_SLEEP_TIMER_) + sysTime = halGetTimeOfSleepTimer(); + sysTime |= ((BcTime_t)halSleepTimerOvfw << 32); + #else + sysTime = halGetTimeOfAppTimer(); + sysTime |= ((BcTime_t)halAppTimeOvfw << 32); + #endif + + return sysTime; +} + +// eof appTimer.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/eeprom.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/eeprom.c new file mode 100644 index 00000000..8e17055b --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/eeprom.c @@ -0,0 +1,156 @@ +/**************************************************************************//** + \file eeprom.c + + \brief Implementation of the EEPROM interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Types section +******************************************************************************/ +typedef enum +{ + EEPROM_IDLE = 0, + EEPROM_BUSY +} EepromState_t; + +/****************************************************************************** + Global variables section +******************************************************************************/ +EepromState_t halEepromState = EEPROM_IDLE; // state +HAL_EepromParams_t halEepromParams; +void (*halEepromDone)(); + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Reads some number of bytes defined by HAL_EepromParams_t from the EEPROM. +Parameters: + params - address of HAL_EepromParams_t defined by user. + readDone - callback method +Returns: + 0 - success. + -1 - the EEPROM has request that was not completed, + number of byte to read too much. + -2 - eeprom is busy +******************************************************************************/ +int HAL_ReadEeprom(HAL_EepromParams_t *params, void (*readDone)()) +{ + uint16_t i; + + if (EEPROM_IDLE != halEepromState) + return -2; + if (NULL == params) + return -1; + if ((uint16_t)(params->address + params->length) > EEPROM_DATA_MEMORY_SIZE) + return -1; + + halEepromState = EEPROM_BUSY; + halEepromDone = readDone; + halEepromParams = *params; + halWaitEepromReady(); // wait for completion of previous operation + for (i = 0; i < halEepromParams.length; i++) + { + halEepromParams.data[i] = halReadEeprom(halEepromParams.address++); + } + halEepromParams.length = 0; + halPostTask3(HAL_EE_READY); + + return 0; +} + +/****************************************************************************** +Writes number of bytes defined by HAL_EepromParams_t to EEPROM. +By writeDone parameter user can control if write operation will be asynchronous +or synchronous. +Parameters: + params - address of HAL_EepromParams_t defined by user. + writeDone - address of callback. if writeDone is NULL write operation will be + synchronous. +Returns: + 0 - success. + -1 - the EEPROM has request that was not completed, + number of byte to write too much. + -2 - eeprom is busy +******************************************************************************/ +int HAL_WriteEeprom(HAL_EepromParams_t *params, void (*writeDone)()) +{ + uint16_t i; + + if (EEPROM_IDLE != halEepromState) + return -2; + if (NULL == params) + return -1; + if ((uint16_t)(params->address + params->length) > EEPROM_DATA_MEMORY_SIZE) + return -1; + + halEepromState = EEPROM_BUSY; + halEepromParams = *params; + halEepromDone = writeDone; + if (halEepromDone) + {// asynchronous operation + halEepromWrite(HAL_EEPROM_WRITE_MASK_INT, halEepromParams.address++, *halEepromParams.data++); + halEepromParams.length--; + return 0; + } + for (i = 0; i < halEepromParams.length; i++) + { + halEepromWrite(HAL_EEPROM_WRITE_MASK, halEepromParams.address++, *halEepromParams.data++); + } + halWaitEepromReady(); // wait for completion of previous write + halEepromState = EEPROM_IDLE; + + return 0; +} + +/****************************************************************************** +Checks the eeprom state. + +Returns: + true - eeprom is busy; + false - eeprom is free; +******************************************************************************/ +bool HAL_IsEepromBusy(void) +{ + if (EEPROM_BUSY == halEepromState) + return true; + else + return false; +} + +/****************************************************************************** +Interrupt handler about write completion to EEPROM. +******************************************************************************/ +void halSigEepromReadyHandler(void) +{ + if (!halEepromParams.length) + { + halEepromState = EEPROM_IDLE; + if (NULL != halEepromDone) + halEepromDone(); + return; + } + halEepromWrite(HAL_EEPROM_WRITE_MASK_INT, halEepromParams.address++, *halEepromParams.data++); + halEepromParams.length--; +} +//eof eeprom.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/halTaskManager.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/halTaskManager.c new file mode 100644 index 00000000..2c647084 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/halTaskManager.c @@ -0,0 +1,305 @@ +/**************************************************************************//** + \file halTaskManager.c + + \brief Implemenattion of HAL task manager. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 10/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + Global variables section +******************************************************************************/ +void (* extHandler)(void); + +/****************************************************************************** + Prototypes section +******************************************************************************/ +/**************************************************************************//** +\brief Interrupt handler of appTimer clock. +******************************************************************************/ +void halAppTimerHandler(void); + +/**************************************************************************//** +\brief HAL USART task. Exact ection depends on USART internal task. +******************************************************************************/ +void halSigUsartHandler(void); + +/**************************************************************************//** +\brief twi end of sending handler +******************************************************************************/ +void halSig2WireSerialHandler(void); + +/**************************************************************************//** +\brief Interrupt handler about write completion to EEPROM. +******************************************************************************/ +void halSigEepromReadyHandler(void); + +/**************************************************************************//** +\brief Interrupt handler about sleep interval was completed. +******************************************************************************/ +void halAsyncTimerHandler(void); + +/***************************************************************************//** +\brief Shutdown system. \n + NOTES: \n + the application should be sure the poweroff will not be \n + interrupted after the execution of the sleep(). +*******************************************************************************/ +void halPowerOff(void); + +/**************************************************************************//** +\brief ADC interrupt handler. +******************************************************************************/ +void halSigAdcHandler(void); + +/**************************************************************************//** +\brief Endpoint interrupt handler. +******************************************************************************/ +void halEndPointHandler(void); + +/**************************************************************************//** +\brief usb suspend interrupt handler. +******************************************************************************/ +void halSuspendHandler(void); + +/**************************************************************************//** +\brief usb resume interrupt handler. +******************************************************************************/ +void halResumeHandler(void); + +/**************************************************************************//** +\brief usb bus reset interrupt handler. +******************************************************************************/ +void halBusResetHandler(void); + +/**************************************************************************//** +\brief Handler for task manager. It is executed when system has waked up. +******************************************************************************/ +void halWakeupHandler(void); + +/**************************************************************************//** +\brief Security Module request handler. +******************************************************************************/ +void halSmRequestHandler(void); + +/**************************************************************************//** +\brief Synchronization system time which based on sleep timer. +******************************************************************************/ +void halSleepSystemTimeSynchronize(void); + +/**************************************************************************//** +\brief Slave spi reception complete interrupt handler. +******************************************************************************/ +void halSpiRxByteComplete(void); + +/****************************************************************************** + Global variables section +******************************************************************************/ +volatile uint8_t halTaskFlags0 = 0; +volatile uint8_t halTaskFlags1 = 0; +volatile uint8_t halTaskFlags2 = 0; +volatile uint8_t halTaskFlags3 = 0; +volatile uint8_t halTaskFlags4 = 0; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +HAL task handler. +******************************************************************************/ +void HAL_TaskHandler() +{ + if (0) + { + } +#ifdef HAL_USE_TIMER2_COMPA + else if (halTaskFlags0 & HAL_ASYNC_TIMER) + { + ATOMIC_SECTION_ENTER + halTaskFlags0 &= (~HAL_ASYNC_TIMER); + ATOMIC_SECTION_LEAVE + halAsyncTimerHandler(); + } +#endif // HAL_USE_TIMER2_COMPA + +#ifdef HAL_USE_TIMER2_COMPA + else if (halTaskFlags0 & HAL_SYNC_SLEEP_TIME) + { + ATOMIC_SECTION_ENTER + halTaskFlags0 &= (~HAL_SYNC_SLEEP_TIME); + ATOMIC_SECTION_LEAVE + halSleepSystemTimeSynchronize(); + } +#endif // HAL_USE_TIMER2_COMPA + +#ifdef HAL_USE_SPI + else if (halTaskFlags2 & HAL_TASK_SPI) + { + ATOMIC_SECTION_ENTER + halTaskFlags2 &= (~HAL_TASK_SPI); + ATOMIC_SECTION_LEAVE + halSpiRxByteComplete(); + } +#endif // HAL_USE_SPI + +#ifdef HAL_USE_USART + else if (halTaskFlags2 & HAL_TASK_USART) + { + ATOMIC_SECTION_ENTER + halTaskFlags2 &= (~HAL_TASK_USART); + ATOMIC_SECTION_LEAVE + halSigUsartHandler(); + } +#endif // HAL_USE_USART + +#ifdef HAL_USE_ADC + else if (halTaskFlags3 & HAL_ADC) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_ADC); + ATOMIC_SECTION_LEAVE + halSigAdcHandler(); + } +#endif // HAL_USE_ADC + +#ifdef HAL_USE_EE_READY + else if (halTaskFlags3 & HAL_EE_READY) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_EE_READY); + ATOMIC_SECTION_LEAVE + halSigEepromReadyHandler(); + } +#endif // HAL_USE_EE_READY + +#ifdef HAL_USE_USB + else if (halTaskFlags3 & HAL_USB_ENDPOINTS) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_USB_ENDPOINTS); + ATOMIC_SECTION_LEAVE + halEndPointHandler(); + } +#endif // HAL_USE_USB + +#ifdef HAL_USE_USB + else if (halTaskFlags3 & HAL_USB_SUSPEND) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_USB_SUSPEND); + ATOMIC_SECTION_LEAVE + halSuspendHandler(); + } +#endif // HAL_USE_USB + +#ifdef HAL_USE_USB + else if (halTaskFlags3 & HAL_USB_RESUME) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_USB_RESUME); + ATOMIC_SECTION_LEAVE + halResumeHandler(); + } +#endif // HAL_USE_USB + +#ifdef _HAL_HW_AES_ + else if (halTaskFlags3 & HAL_SM_REQ) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_SM_REQ); + ATOMIC_SECTION_LEAVE + halSmRequestHandler(); + } +#endif // _HAL_HW_AES_ + +#ifdef HAL_USE_USB + else if (halTaskFlags3 & HAL_USB_BUS_RESET) + { + ATOMIC_SECTION_ENTER + halTaskFlags3 &= (~HAL_USB_BUS_RESET); + ATOMIC_SECTION_LEAVE + halBusResetHandler(); + } +#endif // HAL_USE_USB + +#ifdef HAL_USE_WAKEUP + else if (halTaskFlags4 & HAL_WAKEUP) + { + ATOMIC_SECTION_ENTER + halTaskFlags4 &= (~HAL_WAKEUP); + ATOMIC_SECTION_LEAVE + halWakeupHandler(); + } +#endif + +#ifdef HAL_USE_TWI + else if (halTaskFlags4 & HAL_TWI) + { + ATOMIC_SECTION_ENTER + halTaskFlags4 &= (~HAL_TWI); + ATOMIC_SECTION_LEAVE + halSig2WireSerialHandler(); + } +#endif // HAL_USE_TWI + +#ifdef HAL_USE_TIMER4_COMPA + else if (halTaskFlags4 & HAL_TIMER4_COMPA) + { + ATOMIC_SECTION_ENTER + halTaskFlags4 &= (~HAL_TIMER4_COMPA); + ATOMIC_SECTION_LEAVE + halAppTimerHandler(); + } +#endif // HAL_USE_TIMER4_COMPA + +#ifdef HAL_USE_SLEEP + else if (halTaskFlags4 & HAL_SLEEP) + { + ATOMIC_SECTION_ENTER + halTaskFlags4 &= (~HAL_SLEEP); + ATOMIC_SECTION_LEAVE + halPowerOff(); + } +#endif // HAL_USE_SLEEP + +#ifdef HAL_USE_EXT_HANDLER + else if (halTaskFlags4 & HAL_EXT_HANDLER) + { + ATOMIC_SECTION_ENTER + halTaskFlags4 &= (~HAL_EXT_HANDLER); + ATOMIC_SECTION_LEAVE + if (extHandler) + extHandler(); + } +#endif // HAL_USE_EXT_HANDLER + + if (halTaskFlags0 || + halTaskFlags1 || + halTaskFlags2 || + halTaskFlags3 || + halTaskFlags4) + { + SYS_PostTask(HAL_TASK_ID); + } +} + +// eof halTaskManager.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c new file mode 100644 index 00000000..340981e1 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/i2cPacket.c @@ -0,0 +1,371 @@ +/**************************************************************************//** + \file i2cPacket.c + + \brief Provides the functionality for the writing and the reading \n + of packets through the TWI. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +/* states of the i2c transaction */ +#define I2C_CLOSE 0 +#define I2C_IDLE 1 +#define I2C_WRITE_IADDR_WRITE_DATA 2 +#define I2C_WRITE_IADDR_READ_DATA 3 +#define I2C_WRITE_DATA 4 +#define I2C_READ_DATA 5 +#define I2C_TRANSAC_SUCCESS 6 +#define I2C_TRANSAC_FAIL 7 + +/****************************************************************************** + Types section +******************************************************************************/ +typedef struct +{ + volatile uint8_t* data; // bytes to write to the i2c bus + volatile uint8_t length; // length in bytes of the request + volatile uint8_t index; // current index of read/write byte + volatile uint8_t addr; // destination address + volatile uint32_t intAddress; // internal address inner i2c device + void (*done)(bool result); // callback +} HalI2cPacketControl_t; + +/****************************************************************************** + Global variables section +******************************************************************************/ +// current state of the i2c request +volatile uint8_t halI2cPacketState = I2C_CLOSE; +HalI2cPacketControl_t halI2cPacketControl; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Resets TWI bus and i2c HAL. +******************************************************************************/ +void halI2cBusReset(void) +{ + halI2cPacketState = I2C_TRANSAC_FAIL; + halResetI2c(); + halPostTask4(HAL_TWI); +} + +/****************************************************************************** +Opens resource. +Parameters: + i2cMode - pointer to clock rate structure. +Returns: + Returns: + -1 - resource was opened or pointer is NULL + 0 - success. +******************************************************************************/ +int HAL_OpenI2cPacket(HAL_i2cMode_t *i2cMode) +{ + if (NULL == i2cMode) + return -1; + if (I2C_CLOSE == halI2cPacketState) + { + halInitI2c(i2cMode); + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.index = 0; + return 0; + } + return -1; +} + +/****************************************************************************** +Closes resource. +Returns: + -1 - resource was not opened. + 0 - success. +******************************************************************************/ +int HAL_CloseI2cPacket(void) +{ + if (I2C_CLOSE != halI2cPacketState) + { + halI2cPacketControl.done = NULL; + halI2cPacketState = I2C_CLOSE; + return 0; + } + return -1; +} + +/****************************************************************************** +Writes the series of bytes out to the TWI bus. +Parameters: + param - pointer to HAL_I2cParams_t structure +Returns: + 0 - the bus is free and the request is accepted. + -1 - other case. +******************************************************************************/ +int HAL_WriteI2cPacket(HAL_I2cParams_t *param) +{ + if ((I2C_IDLE == halI2cPacketState) && param) + { + halI2cPacketControl.addr = param->id; + halI2cPacketControl.data = param->data; + halI2cPacketControl.index = param->lengthAddr; + halI2cPacketControl.length = param->length; + halI2cPacketControl.done = param->f; + halI2cPacketControl.intAddress = param->internalAddr; + } + else + { + return -1; + } + + if (HAL_NO_INTERNAL_ADDRESS == halI2cPacketControl.index) + halI2cPacketState = I2C_WRITE_DATA; + else + halI2cPacketState = I2C_WRITE_IADDR_WRITE_DATA; + halSendStartI2c(); + return 0; +} + +/****************************************************************************** +Reads the series of bytes out to the TWI bus. +Parameters: + param - pointer to HAL_I2cParams_t structure +Returns: + 0 - the bus is free and the request is accepted. + -1 - other case. +******************************************************************************/ +int HAL_ReadI2cPacket(HAL_I2cParams_t *param) +{ + if ((I2C_IDLE == halI2cPacketState) && param) + { + halI2cPacketControl.addr = param->id; + halI2cPacketControl.index = param->lengthAddr; + halI2cPacketControl.length = param->length; + halI2cPacketControl.data = param->data; + halI2cPacketControl.done = param->f; + halI2cPacketControl.intAddress = param->internalAddr; + } + else + { + return -1; + } + + if (HAL_NO_INTERNAL_ADDRESS == halI2cPacketControl.index) + halI2cPacketState = I2C_READ_DATA; + else + halI2cPacketState = I2C_WRITE_IADDR_READ_DATA; + halSendStartI2c(); + return 0; +} + +/****************************************************************************** +Notification about the start condition was sent. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halSendStartDoneI2c(void) +{ + if ((I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) || + (I2C_WRITE_IADDR_READ_DATA == halI2cPacketState) || + (I2C_WRITE_DATA == halI2cPacketState)) + { + halWriteI2c(((halI2cPacketControl.addr << 1) + 0)); + } + else if (I2C_READ_DATA == halI2cPacketState) + { + halWriteI2c(((halI2cPacketControl.addr << 1) + 1)); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Sending data to i2c bus. If last byte then send stop condition and post task. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halWriteData(void) +{ + if (halI2cPacketControl.index < halI2cPacketControl.length) + { + halWriteI2c(halI2cPacketControl.data[halI2cPacketControl.index++]); + } + else + { + halI2cPacketState = I2C_TRANSAC_SUCCESS; + halSendStopI2c(); + halPostTask4(HAL_TWI); + } +} + +/****************************************************************************** +Sending internal device address to i2c bus. If address is sent then switch i2c +hal state. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halWriteInternalAddress(void) +{ + uint8_t data; + + data = (uint8_t)(halI2cPacketControl.intAddress >> --halI2cPacketControl.index * 8); + halWriteI2c(data); + + if (0 == halI2cPacketControl.index) + { + if (I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) + halI2cPacketState = I2C_WRITE_DATA; + else + halI2cPacketState = I2C_READ_DATA; + } +} + +/****************************************************************************** +Notification that byte was written to the TWI. +Parameters: + result - contains result of previous operation. +Returns: + none. +******************************************************************************/ +void halWriteDoneI2c(void) +{ + if (I2C_WRITE_DATA == halI2cPacketState) + { + halWriteData(); + } + else if ((I2C_WRITE_IADDR_WRITE_DATA == halI2cPacketState) || (I2C_WRITE_IADDR_READ_DATA == halI2cPacketState)) + { + halWriteInternalAddress(); + } + else if (I2C_READ_DATA == halI2cPacketState) + { + halSendStartI2c(); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that address byte was written to the TWI and was read ACK. +Starts reading data. +Parameters: + none. +Returns: + none. +******************************************************************************/ +void halMasterReadWriteAddressAckI2c(void) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + if (1 == halI2cPacketControl.length) + halReadI2c(false); // send nack + else + halReadI2c(true); // send ack + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that byte was read from the TWI. +Parameters: + data - contains byte that was read. +Returns: + none. +******************************************************************************/ +void halReadDoneI2c(uint8_t data) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + halI2cPacketControl.data[halI2cPacketControl.index++] = data; + if (halI2cPacketControl.index < (halI2cPacketControl.length - 1)) + halReadI2c(true); // send ACK + else + halReadI2c(false); // send NACK + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Notification that last byte was read from the TWI. Needs send STOP condition +on bus. +Parameters: + data - contains byte that was read. +Returns: + none. +******************************************************************************/ +void halReadLastByteDoneI2c(uint8_t data) +{ + if (I2C_READ_DATA == halI2cPacketState) + { + halI2cPacketControl.data[halI2cPacketControl.index++] = data; + halI2cPacketState = I2C_TRANSAC_SUCCESS; + halSendStopI2c(); + halPostTask4(HAL_TWI); + } + else + { // abnormal + halI2cBusReset(); + } +} + +/****************************************************************************** +Waits for end of sending and calls user's callback +******************************************************************************/ +void halSig2WireSerialHandler(void) +{ + if (halI2cPacketControl.done) + { + if (I2C_TRANSAC_SUCCESS == halI2cPacketState) + { + halWaitEndOfStopStation(); + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.done(true); + } + else + { + halI2cPacketState = I2C_IDLE; + halI2cPacketControl.done(false); + } + } + else + { + halI2cPacketState = I2C_IDLE; + } +} +// eof i2cPacket.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/irq.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/irq.c new file mode 100644 index 00000000..c681ba74 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/irq.c @@ -0,0 +1,143 @@ +/**************************************************************************//** + \file irq.c + + \brief Implementation of IRQ interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + External global variables section +******************************************************************************/ +extern IrqCallback_t IrqCallbackList[HAL_NUM_IRQ_LINES]; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** + Registers user's irqNumber interrupt + Parameters: + irqNumber - IRQ number + irqMode - Interrupt sence control + f - user's interrupt handler. Handler must be executed less than 100 us. + Returns: + -1 - if irqNumber is out of range, not valid irq mode, invalid interrupt handler + or such interrupt has been already registered. + 0 - otherwise. +******************************************************************************/ +int HAL_RegisterIrq(HAL_IrqNumber_t irqNumber, HAL_IrqMode_t irqMode, void (*f)(void)) +{ + uint8_t irqOffsetNumber = irqNumber - HAL_FIRST_VALID_IRQ; + + // irqNumber is out of range + if (irqOffsetNumber >= HAL_NUM_IRQ_LINES) + return -1; + // Such interrupt has been already register + if (NULL != IrqCallbackList[irqOffsetNumber]) + return -1; + // not valid irq mode + if (IRQ_HIGH_LEVEL == irqMode) + return -1; + // invalid interrupt handler + if (NULL == f) + return -1; + + /* type HAL_IrqMode_t has not valid IRQ_HIGH_LEVEL state, + * because for saving to register all states need decrement after IRQ_LOW_LEVEL state. */ + if (IRQ_LOW_LEVEL == irqMode) + halSetIrqConfig(irqNumber, irqMode); + else + halSetIrqConfig(irqNumber, irqMode - 1); + + IrqCallbackList[irqOffsetNumber] = f; + return 0; +} + +/****************************************************************************** + Enables irqNumber interrupt + Parameters: + irqNumber - IRQ number + Returns: + -1 - if irqNumber is out of range or has not been + registered yet. + 0 - otherwise. +******************************************************************************/ +int HAL_EnableIrq(HAL_IrqNumber_t irqNumber) +{ + uint8_t irqOffsetNumber = irqNumber - HAL_FIRST_VALID_IRQ; + // irqNumber is out of range + if (irqOffsetNumber >= HAL_NUM_IRQ_LINES) + return -1; + // Interrupt has not been opened yet + if (NULL == IrqCallbackList[irqOffsetNumber]) + return -1; + halEnableIrqInterrupt(irqNumber); + return 0; +} + +/****************************************************************************** + Disables irqNumber interrupt + Parameters: + irqNumber - IRQ number + Returns: + -1 - if irqNumber is out of range or has not been + registered yet. + 0 - otherwise. +******************************************************************************/ +int HAL_DisableIrq(HAL_IrqNumber_t irqNumber) +{ + uint8_t irqOffsetNumber = irqNumber - HAL_FIRST_VALID_IRQ; + // irqNumber is out of range + if (irqOffsetNumber >= HAL_NUM_IRQ_LINES) + return -1; + // Interrupt has not been opened yet + if (NULL == IrqCallbackList[irqOffsetNumber]) + return -1; + halDisableIrqInterrupt(irqNumber); + return 0; +} + +/****************************************************************************** + Unregisters user's irqNumber interrupt + Parameters: + irqNumber - IRQ number + Returns: + -1 - if irqNumber is out of range or has not been + registered yet. + 0 - otherwise. +******************************************************************************/ +int HAL_UnregisterIrq(HAL_IrqNumber_t irqNumber) +{ + uint8_t irqOffsetNumber = irqNumber - HAL_FIRST_VALID_IRQ; + // irqNumber is out of range + if (irqOffsetNumber >= HAL_NUM_IRQ_LINES) + return -1; + // Interrupt has not been opened yet + if (NULL == IrqCallbackList[irqOffsetNumber]) + return -1; + // Disable external interrupt request + halDisableIrqInterrupt(irqNumber); + halClrIrqConfig(irqNumber); + IrqCallbackList[irqOffsetNumber] = NULL; + return 0; +} + +// eof irq.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/pwm.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/pwm.c new file mode 100644 index 00000000..ad7b18a2 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/pwm.c @@ -0,0 +1,165 @@ +/**************************************************************************//** + \file pwm.c + + \brief Implementation of PWM interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 10/11/08 A. Taradov - Created + 5/04/11 A.Razinkov - Refactored +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + Defines section +******************************************************************************/ + +/****************************************************************************** + Constants section +******************************************************************************/ + +/****************************************************************************** + Global variables section +******************************************************************************/ + +/****************************************************************************** + Implementations section +******************************************************************************/ + +/**************************************************************************//** +\brief Initializes the PWM. + +\param [in] pwmUnit - PWM unit number. + Equal to ID of Timer/Counter witch serves PWM module. + +\return operation status +******************************************************************************/ +int HAL_OpenPwm(HAL_PwmUnit_t pwmUnit) +{ + /* Check PWM unit */ + if ((PWM_UNIT_1 == pwmUnit) || (PWM_UNIT_3 == pwmUnit)) + halOpenPwm(pwmUnit); + else + return PWM_INVALID_UNIT_STATUS; + + return PWM_SUCCESS_STATUS; +} + +/**************************************************************************//** +\brief Starts PWM on specified channel. + +\param [in] descriptor - PWM channel descriptor. + +\return operation status +******************************************************************************/ +int HAL_StartPwm(HAL_PwmDescriptor_t *descriptor) +{ + /* Invalid PWM channel specified */ + if (PWM_INVALID_CHANNEL <= descriptor->channel) + return PWM_INVALID_CHANNEL_STATUS; + /* Check PWM unit */ + if ((PWM_UNIT_1 == descriptor->unit) || (PWM_UNIT_3 == descriptor->unit)) + { + halPreparePwmChannelAccess(descriptor); + halStartPwm(descriptor); + } + else + return PWM_INVALID_UNIT_STATUS; + + return PWM_SUCCESS_STATUS; +} + +/**************************************************************************//** +\brief Stops PWM on specified channel. + +\param [in] descriptor - PWM channel descriptor. + +\return operation status +******************************************************************************/ +int HAL_StopPwm(HAL_PwmDescriptor_t *descriptor) +{ + /* Invalid PWM channel specified */ + if (PWM_INVALID_CHANNEL <= descriptor->channel) + return PWM_INVALID_CHANNEL_STATUS; + else + halStopPwm(descriptor); + + return PWM_SUCCESS_STATUS; +} + +/**************************************************************************//** +\brief Sets base frequency of module. Common for all module channels. + +\param [in] pwmUnit - PWM unit number. Equal to corresponding Timer/Counter ID. +\param [in] top - value for the TOP register. +\param [in] prescaler - clock prescaler. + +\return operation status +******************************************************************************/ +int HAL_SetPwmFrequency(HAL_PwmUnit_t pwmUnit, uint16_t top, HAL_PwmPrescaler_t prescaler) +{ + /* Check prescaler value */ + if (PWM_PRESCALER_INVALID <= prescaler) + return PWM_INVALID_PRESCALER_STATUS; + else halSetPwmFrequency(pwmUnit, top, prescaler); + + return PWM_SUCCESS_STATUS; +} + +/**************************************************************************//** +\brief Sets compare value for the PWM channel. + +\param [in] descriptor - PWM channel descriptor. + +\return operation status +******************************************************************************/ +int HAL_SetPwmCompareValue(HAL_PwmDescriptor_t *descriptor, uint16_t cmpValue) +{ + /* Invalid PWM channel specified */ + if (PWM_INVALID_CHANNEL <= descriptor->channel) + return PWM_INVALID_CHANNEL_STATUS; + /* Check PWM unit */ + if ((PWM_UNIT_1 == descriptor->unit) || (PWM_UNIT_3 == descriptor->unit)) + halSetPwmCompareValue(descriptor, cmpValue); + else + return PWM_INVALID_UNIT_STATUS; + + return PWM_SUCCESS_STATUS; +} + +/**************************************************************************//** +\brief Closes the PWM. + +\param [in] pwmUnit - PWM unit number. + Equal to ID of Timer/Counter witch serves PWM module. + +\return operation status +******************************************************************************/ +int HAL_ClosePwm(HAL_PwmUnit_t pwmUnit) +{ + /* Check PWM unit */ + if ((PWM_UNIT_1 == pwmUnit) || (PWM_UNIT_3 == pwmUnit)) + halClosePwm(pwmUnit); + else + return PWM_INVALID_UNIT_STATUS; + + return PWM_SUCCESS_STATUS; +} + +// eof pwm.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/resetReason.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/resetReason.c new file mode 100644 index 00000000..0fecaa11 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/resetReason.c @@ -0,0 +1,59 @@ +/**************************************************************************//** + \file halWdtInit.c + + \brief Implementation of the reset reason interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 5/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include + +/****************************************************************************** + External variables section +******************************************************************************/ +extern uint8_t halResetReason; // contains the reset reason + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Returns the reset reason. +Parameters: + none. +Returns: + The reason of reset. +******************************************************************************/ +HAL_ResetReason_t HAL_ReadResetReason(void) +{ + return (HAL_ResetReason_t)halResetReason; +} + +/****************************************************************************** +Software reset. +******************************************************************************/ +void HAL_WarmReset(void) +{ + + halResetReason = TEMP_WARM_RESET; + wdt_enable(0); + while(1); +} +//eof resetReason.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleep.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleep.c new file mode 100644 index 00000000..1ad72df2 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleep.c @@ -0,0 +1,79 @@ +/**************************************************************************//** + \file sleep.c + + \brief The implementation of common sleep and wake up. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 1/12/09 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define HAL_NULL_POINTER -1 +#define HAL_SLEEP_TIMER_HAS_ALREADY_STARTED -3 +#define HAL_SLEEP_TIMER_IS_BUSY -2 +#define HAL_SLEEP_SYSTEM_HAS_ALREADY_STARTED -3 + +/****************************************************************************** + Global variables section +******************************************************************************/ +HalSleepControl_t halSleepControl = +{ + .wakeupStation = HAL_ACTIVE_MODE, + .sleepTimerState = HAL_SLEEP_TIMER_IS_STOPPED +}; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Starts sleep timer and HAL sleep. When system is wake up send callback +\param[in] + sleepParam - pointer to sleep structure. +\return + -1 - bad pointer, \n + -2 - sleep timer is busy, \n + -3 - sleep system has been started. + 0 - success. +******************************************************************************/ +int HAL_StartSystemSleep(HAL_Sleep_t *sleepParam) +{ + HAL_SleepTimer_t sleepTimer; + int sleepTimerStatus; + + if (!sleepParam) + return HAL_NULL_POINTER; + + halSleepControl.callback = sleepParam->callback; + sleepTimer.interval = sleepParam->sleepTime; + sleepTimer.mode = TIMER_ONE_SHOT_MODE; + sleepTimer.callback = NULL; + + sleepTimerStatus = HAL_StartSleepTimer(&sleepTimer); + if ((HAL_NULL_POINTER == sleepTimerStatus) || (HAL_SLEEP_TIMER_HAS_ALREADY_STARTED == sleepTimerStatus)) + return HAL_SLEEP_TIMER_IS_BUSY; + + if (-1 == HAL_Sleep()) + return HAL_SLEEP_SYSTEM_HAS_ALREADY_STARTED; + + return 0; +} + +//eof sleep.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleepTimer.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleepTimer.c new file mode 100644 index 00000000..f83d2446 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/sleepTimer.c @@ -0,0 +1,126 @@ +/**************************************************************************//** + \file sleepTimer.c + + \brief The implementation of the sleep timer. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 29/05/07 E. Ivanov - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define HAL_NULL_POINTER -1 +#define HAL_TIME_CAN_NOT_BE_COUNTED -2 +#define HAL_SLEEP_TIMER_HAS_ALREADY_STARTED -3 +#define HAL_SLEEP_TIMER_HAS_ALREADY_STOPPED -1 + +/****************************************************************************** + External global variables section +******************************************************************************/ +extern HalSleepControl_t halSleepControl; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Starts sleep timer. Interval must be greater one tick time. + Parameters: + sleepTimer - address of the HAL_SleepTimer_t. + Returns: + -1 - NULL pointer, \n + -2 - interval can not be counted out, \n + -3 - sleep timer has already started. \n + 0 - otherwise. +******************************************************************************/ +int HAL_StartSleepTimer(HAL_SleepTimer_t *sleepTimer) +{ + uint32_t tempValue; + + if (!sleepTimer) + return HAL_NULL_POINTER; + + // Convert millisecond interval to the sleep timer ticks. + tempValue = (halSleepTimerFrequency() * sleepTimer->interval) / 1000ul; + if (!tempValue) + return HAL_TIME_CAN_NOT_BE_COUNTED;// Can't count out interval + + if (HAL_SLEEP_TIMER_IS_STARTED == halSleepControl.sleepTimerState) // there is active timer + return HAL_SLEEP_TIMER_HAS_ALREADY_STARTED; + + halSleepControl.sleepTimerState = HAL_SLEEP_TIMER_IS_STARTED; + halSleepControl.sleepTimer = *sleepTimer; + // Start asynchronous timer2. + halSetSleepTimerInterval(tempValue); + return 0; +}// end sleepTimer_start + +/****************************************************************************** +Removes timer. +Parameters: + sleepTimer - is not used now. For capabilities for old version. +Returns: + -1 - there is no active sleep timer. + 0 - otherwise. +******************************************************************************/ +int HAL_StopSleepTimer(HAL_SleepTimer_t *sleepTimer) +{ + (void)sleepTimer; + + // there is no active timer + if (HAL_SLEEP_TIMER_IS_STOPPED == halSleepControl.sleepTimerState) + return HAL_SLEEP_TIMER_HAS_ALREADY_STOPPED; + halClearTimeControl(); + halSleepControl.sleepTimerState = HAL_SLEEP_TIMER_IS_STOPPED; + + return 0; +} + +/****************************************************************************** +Interrupt handler about sleep interval was completed. +******************************************************************************/ +void halAsyncTimerHandler(void) +{ + // there isn't work timer + if (HAL_SLEEP_TIMER_IS_STOPPED == halSleepControl.sleepTimerState) + return; + + if (TIMER_REPEAT_MODE == halSleepControl.sleepTimer.mode) + { + if (halSleepControl.sleepTimer.callback) + halSleepControl.sleepTimer.callback(); + + // user can stop timer in callback + if (HAL_SLEEP_TIMER_IS_STOPPED == halSleepControl.sleepTimerState) + return; + + halSetSleepTimerInterval(halSleepControl.sleepTimer.interval); + } + else + { + halSleepControl.sleepTimerState = HAL_SLEEP_TIMER_IS_STOPPED; + if (halSleepControl.sleepTimer.callback) + halSleepControl.sleepTimer.callback(); + } +} + +//eof sleepTimer.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/spi.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/spi.c new file mode 100644 index 00000000..cd4c55b0 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/spi.c @@ -0,0 +1,602 @@ +/**************************************************************************//** + \file spi.c + + \brief Implementation of USART SPI mode, hardware-independent module. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 29/05/08 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Global functions prototypes section +******************************************************************************/ +void halSetUsartSpiConfig(HAL_SpiDescriptor_t *descriptor); +void halSetSlaveSpiConfig(HAL_SpiDescriptor_t *descriptor); + +/****************************************************************************** + External global variables section +******************************************************************************/ +extern HAL_UsartDescriptor_t *halPointDescrip[NUM_USART_CHANNELS]; +#if defined(ATMEGA128RFA1) + extern HAL_SpiDescriptor_t *halRealSpiDescripPointer; + extern volatile uint8_t rxSlaveBuffer[HAL_SPI_RX_BUFFER_LENGTH]; +#endif + +/****************************************************************************** + Static functions prototypes section +******************************************************************************/ +static bool isClosedPd(void *pointer); +static bool isOpenedPd(void *pointer); +static int halCheckUsartDescriptor(HAL_SpiDescriptor_t *descriptor, bool(* predicate)(void *)); +static int halOpenUsartSpi(HAL_SpiDescriptor_t *descriptor); +static int halCloseUsartSpi(HAL_SpiDescriptor_t *descriptor); +static int halFillServiceInfo(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length, uint8_t transac); +static int halWriteUsartSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length); +static int halReadUsartSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length); +#if defined(ATMEGA128RFA1) +static int halCheckSpiDescriptor(HAL_SpiDescriptor_t *descriptor, bool(* predicate)(void *)); +static int halOpenRealSpi(HAL_SpiDescriptor_t *descriptor); +static int halCloseRealSpi(HAL_SpiDescriptor_t *descriptor); +static int halWriteRealSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length); +static int halReadRealSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length); +#endif + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Predicate for check of closed station. +\param[in] + pointer - pointer to some descriptor. +\return + true - interface is closed; + false - interface is not closed. +******************************************************************************/ +static bool isClosedPd(void *pointer) +{ + return pointer ? false : true; +} + +/**************************************************************************//** +\brief Predicate for check of opened station. +\param[in] + pointer - pointer to some descriptor. +\return + true - interface is opened; + false - interface is not opened. +******************************************************************************/ +static bool isOpenedPd(void *pointer) +{ + return pointer ? true : false; +} + +/**************************************************************************//** +\brief Check correctenss of the usart spi descriptor. +\param[in] + descriptor - pointer to the usart spi descriptor. +\param[in] + predicate - check station predicate. +\return + interface index - interface is opened; + -1 - interface is not opened. +******************************************************************************/ +static int halCheckUsartDescriptor(HAL_SpiDescriptor_t *descriptor, bool(* predicate)(void *)) +{ + int i; + + if (NULL == descriptor) + return -1; + + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (false == predicate((void *)halPointDescrip[i])) + return -1; + + return i; +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Check correctenss of the real spi descriptor. +\param[in] + descriptor - pointer to the real spi descriptor. +\param[in] + predicate - check station predicate. +\return + 0 - interface is opened; + -1 - interface is not opened. +******************************************************************************/ +static int halCheckSpiDescriptor(HAL_SpiDescriptor_t *descriptor, bool(* predicate)(void *)) +{ + if (NULL == descriptor) + return -1; + + if (SPI_CHANNEL_2 != descriptor->tty) + return -1; + + if (false == predicate((void *)halRealSpiDescripPointer)) + return -1; + + return 0; +} +#endif + +/**************************************************************************//** +\brief Configure usart in mspi mode. +\param[in] + descriptor - pointer to the usart spi descriptor. +\return + -1 - there not are free resources. + 0 - SPI channel is ready. +******************************************************************************/ +static int halOpenUsartSpi(HAL_SpiDescriptor_t *descriptor) +{ + int i; // Descriptor index + + i = halCheckUsartDescriptor(descriptor, isClosedPd); + if (-1 == i) + return -1; + + if (NULL != descriptor->callback) + { + descriptor->spiDescriptor.txCallback = descriptor->callback; + descriptor->spiDescriptor.tty = descriptor->tty; + } + + halPointDescrip[i] = &descriptor->spiDescriptor; + halSetUsartSpiConfig(descriptor); + return 0; +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Configure spi. +\param[in] + descriptor - pointer to the spi descriptor. +\return + -1 - there are no free resources. + 0 - SPI channel is ready. +******************************************************************************/ +static int halOpenRealSpi(HAL_SpiDescriptor_t *descriptor) +{ + if (-1 == halCheckSpiDescriptor(descriptor, isClosedPd)) + return -1; + + halRealSpiDescripPointer = descriptor; + halRealSpiDescripPointer->spiDescriptor.service.txPointOfRead = 0; + halRealSpiDescripPointer->spiDescriptor.service.txPointOfWrite = 0; + halRealSpiDescripPointer->spiDescriptor.service.rxPointOfRead = 0; + halRealSpiDescripPointer->spiDescriptor.service.rxPointOfWrite = 0; + halSetSlaveSpiConfig(descriptor); + return 0; +} +#endif + +/**************************************************************************//** +\brief Open the SPI interface. +\param[in] + descriptor - pointer to the spi descriptor. +\return + -1 - there not are free resources. + 0 - SPI channel is ready. +******************************************************************************/ +int HAL_OpenSpi(HAL_SpiDescriptor_t *descriptor) +{ +#if defined(ATMEGA128RFA1) + if (SPI_CHANNEL_2 == descriptor->tty) + return halOpenRealSpi(descriptor); + else +#endif + return halOpenUsartSpi(descriptor); +} + +/**************************************************************************//** +\brief Clear the usart channel and pins. +\param[in] + descriptor - pointer to the spi descriptor. +\return + 0 - success + -1 - channel was not opened. +******************************************************************************/ +static int halCloseUsartSpi(HAL_SpiDescriptor_t *descriptor) +{ + int i; + + i = halCheckUsartDescriptor(descriptor, isOpenedPd); + if (-1 == i) + return -1; + + halPointDescrip[i] = NULL; + halClearUsartSpi(descriptor->tty); + return 0; +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Clear the spi channel and pins. +\param[in] + descriptor - pointer to the spi descriptor. +\return + Returns 0 on success or -1 if channel was not opened. +******************************************************************************/ +static int halCloseRealSpi(HAL_SpiDescriptor_t *descriptor) +{ + if (-1 == halCheckSpiDescriptor(descriptor, isClosedPd)) + return -1; + + halRealSpiDescripPointer = NULL; + halClearRealSpi(); + return 0; +} +#endif + +/**************************************************************************//** +\brief Close the SPI channel and pins. +\param[in] + descriptor - pointer to the spi descriptor. +\return + Returns 0 on success or -1 if channel was not opened. +******************************************************************************/ +int HAL_CloseSpi(HAL_SpiDescriptor_t *descriptor) +{ +#if defined(ATMEGA128RFA1) + if (SPI_CHANNEL_2 == descriptor->tty) + return halCloseRealSpi(descriptor); + else +#endif + return halCloseUsartSpi(descriptor); +} + +/**************************************************************************//** +\brief Fill service structure for bus transaction. +\param[in] + descriptor - pointer to the spi descriptor. +\param[in] + buffer -pointer to data buffer. +\param[in] + length - length of the data buffer. +\param[in] + transac - bus transaction type. +\return + -1 - interface is busy; + 0 - success. +******************************************************************************/ +static int halFillServiceInfo(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length, uint8_t transac) +{ + HalUsartService_t *halBufferControl; + + halBufferControl = &descriptor->spiDescriptor.service; + if (halBufferControl->txPointOfWrite != halBufferControl->txPointOfRead) + return -1; // there is unsent data + + descriptor->spiDescriptor.txBuffer = buffer; + descriptor->spiDescriptor.txBufferLength = 0; + halBufferControl->txPointOfWrite = length; + halBufferControl->txPointOfRead = 0; + descriptor->spiDescriptor.rxBuffer = buffer; + descriptor->spiDescriptor.flowControl = transac; + return 0; +} + +/**************************************************************************//** +\brief Writes a length bytes to the usart. \n + Callback function will be used to notify about the finishing transmitting. +\param[in] + descriptor - pointer to spi descriptor +\param[in] + buffer - pointer to application data buffer; +\param[in] + length - number bytes for transfer; +\return + -1 - spi module was not opened, there is unsent data, pointer to the data or + the length are zero; \n + 0 - on success or a number; \n + Number of written bytes if the synchronous method is used(callback is NULL). +******************************************************************************/ +static int halWriteUsartSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + int i; + + if (!buffer || !length) + return -1; + + i = halCheckUsartDescriptor(descriptor, isOpenedPd); + if (-1 == i) + return -1; + + if (&descriptor->spiDescriptor != halPointDescrip[i]) + return -1; // incorrect descriptor + + if (NULL != descriptor->callback) + { + if (-1 == halFillServiceInfo(descriptor, buffer, length, USART_SPI_WRITE_MODE)) + return -1; + + halEnableUsartSpiRxcInterrupt(descriptor->tty); + halEnableUsartSpiDremInterrupt(descriptor->tty); + return 0; + } + else + { + return halSyncUsartSpiWriteData(descriptor->tty, buffer, length); + } +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Writes a length bytes to the spi. \n +\param[in] + descriptor - pointer to spi descriptor +\param[in] + buffer - pointer to application data buffer; +\param[in] + length - number bytes for transfer; +\return + -1 - spi module was not opened, there is unsent data, pointer to the data or + the length are zero; \n + 0 - on success or a number; \n +******************************************************************************/ +static int halWriteRealSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + if (!buffer || !length) + return -1; + + if (-1 == halCheckSpiDescriptor(descriptor, isOpenedPd)) + return -1; + + if (descriptor != halRealSpiDescripPointer) + return -1; // incorrect descriptor + + if (-1 == halFillServiceInfo(descriptor, buffer, length, USART_SPI_WRITE_MODE)) + return -1; + + halSendSpiByte(*buffer); + return 0; +} +#endif + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Put next byte to the spi. +******************************************************************************/ +void halSpiTxByteComplete(void) +{ + HalUsartService_t *halBufferControl; + + halBufferControl = &halRealSpiDescripPointer->spiDescriptor.service; + + if (halBufferControl->txPointOfWrite != halBufferControl->txPointOfRead) + halSendSpiByte(halRealSpiDescripPointer->spiDescriptor.txBuffer[++halBufferControl->txPointOfRead]); +} +#endif + +/**************************************************************************//** +\brief Writes a length bytes to the SPI. \n + Callback function will be used to notify about the finishing transmitting. + (only for master spi) +\param[in] + descriptor - pointer to spi descriptor +\param[in] + buffer - pointer to application data buffer; +\param[in] + length - number bytes for transfer; +\return + -1 - spi module was not opened, there is unsent data, pointer to the data or + the length are zero; \n + 0 - on success or a number; \n + Number of written bytes if the synchronous method is used(callback is NULL), \n + only for master spi. +******************************************************************************/ +int HAL_WriteSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ +#if defined(ATMEGA128RFA1) + if (SPI_CHANNEL_2 == descriptor->tty) + return halWriteRealSpi(descriptor, buffer, length); + else +#endif + return halWriteUsartSpi(descriptor, buffer, length); +} + +/**************************************************************************//** +\brief Reads a number of bytes from the usart.\n + Callback function will be used to notify when the activity is finished.\n + The read data is placed to the buffer. +\param[in] + descriptor - pointer to HAL_SpiDescriptor_t structure +\param[in] + buffer - pointer to the application data buffer +\param[in] + length - number of bytes to transfer +\return + -1 - spi module was not opened, or there is unsent data, or the pointer to + data or the length are NULL; \n + 0 - success; \n + Number of written bytes if the synchronous method is used(callback is NULL). +******************************************************************************/ +static int halReadUsartSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + HAL_UsartDescriptor_t *spiDescrip; + int i; + + if (!buffer || !length) + return -1; + + i = halCheckUsartDescriptor(descriptor, isOpenedPd); + if (-1 == i) + return -1; + + spiDescrip = &descriptor->spiDescriptor; + if (spiDescrip != halPointDescrip[i]) + return -1; // incorrect descriptor + + if (NULL != descriptor->callback) + { + if (-1 == halFillServiceInfo(descriptor, buffer, length, USART_SPI_READ_MODE)) + return -1; + + halEnableUsartSpiRxcInterrupt(descriptor->tty); + halEnableUsartSpiDremInterrupt(descriptor->tty); + return 0; + } + else + { + return halSyncUsartSpiReadData(descriptor->tty, buffer, length); + } +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Reads a number of bytes from spi internal buffer and places them to the buffer. +\param[in] + descriptor - pointer to HAL_SpiDescriptor_t structure +\param[in] + buffer - pointer to the application data buffer +\param[in] + length - number of bytes to transfer +\return + -1 - spi module was not opened, or there is unsent data, or the pointer to + data or the length are NULL; \n + Number of read bytes from spi internal buffer. +******************************************************************************/ +static int halReadRealSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + uint16_t wasRead = 0; + uint16_t poW; + uint16_t poR; + HalUsartService_t *halBufferControl; + + if (!buffer || !length) + return -1; + + if (-1 == halCheckSpiDescriptor(descriptor, isOpenedPd)) + return -1; + + if (descriptor != halRealSpiDescripPointer) + return -1; // incorrect descriptor + + halBufferControl = &halRealSpiDescripPointer->spiDescriptor.service; + ATOMIC_SECTION_ENTER + poW = halBufferControl->rxPointOfWrite; + poR = halBufferControl->rxPointOfRead; + ATOMIC_SECTION_LEAVE + + while ((poR != poW) && (wasRead < length)) + { + buffer[wasRead] = rxSlaveBuffer[poR]; + if (HAL_SPI_RX_BUFFER_LENGTH == ++poR) + poR = 0; + wasRead++; + } + + ATOMIC_SECTION_ENTER + halBufferControl->rxPointOfRead = poR; + halBufferControl->rxBytesInBuffer -= wasRead; + ATOMIC_SECTION_LEAVE + + return wasRead; +} +#endif + +/**************************************************************************//** +\brief For master : writes a number of bytes to the spi.\n + Callback function will be used to notify when the activity is finished.\n + The read data is placed to the buffer. \n + For slave: reads a number of bytes from internal spi buffer and writes them \n + to application buffer. +\param[in] + descriptor - pointer to HAL_SpiDescriptor_t structure +\param[in] + buffer - pointer to the application data buffer +\param[in] + length - number of bytes to transfer +\return + -1 - spi module was not opened, or there is unsent data, or the pointer to + data or the length are NULL; \n + 0 - success for master; \n + Number of written bytes if the synchronous method is used(callback is NULL) for master \n + or number of read bytes from internal buffer to the application buffer for slave. +******************************************************************************/ +int HAL_ReadSpi(HAL_SpiDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ +#if defined(ATMEGA128RFA1) + if (SPI_CHANNEL_2 == descriptor->tty) + return halReadRealSpi(descriptor, buffer, length); + else +#endif + return halReadUsartSpi(descriptor, buffer, length); +} + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Puts the received byte to the cyclic buffer. + +\param[in] + data - data to put. +******************************************************************************/ +void halSpiRxBufferFiller(uint8_t data) +{ + uint16_t old; + HalUsartService_t *halBufferControl; + + if (NULL == halRealSpiDescripPointer) + {// abnormal + halClearRealSpi(); + return; + } + + halBufferControl = &halRealSpiDescripPointer->spiDescriptor.service; + old = halBufferControl->rxPointOfWrite; + + if (HAL_SPI_RX_BUFFER_LENGTH == ++halBufferControl->rxPointOfWrite) + halBufferControl->rxPointOfWrite = 0; + + if (halBufferControl->rxPointOfWrite == halBufferControl->rxPointOfRead) + { // Buffer full. + halBufferControl->rxPointOfWrite = old; + return; + } // Buffer full. + + rxSlaveBuffer[old] = data; + halBufferControl->rxBytesInBuffer++; +} +#endif + +#if defined(ATMEGA128RFA1) +/**************************************************************************//** +\brief Slave spi reception complete interrupt handler. +******************************************************************************/ +void halSpiRxByteComplete(void) +{ + uint16_t number; + + ATOMIC_SECTION_ENTER + number = halRealSpiDescripPointer->spiDescriptor.service.rxBytesInBuffer; + ATOMIC_SECTION_LEAVE + + if (number) + if (NULL != halRealSpiDescripPointer->slave_callback) + halRealSpiDescripPointer->slave_callback(number); +} +#endif + +// eof spi.c + diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/timer.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/timer.c new file mode 100644 index 00000000..ca36cca9 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/timer.c @@ -0,0 +1,114 @@ +/**************************************************************************//** + \file timer.c + + \brief Functions to manipulate by timers list. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 7/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** +Adds timer to the timer's list. +Parameters: + head - address of pointer to head of the timers list. + timer - address of timer that must be added to the list. + sysTime - current time. +Returns: + none. +******************************************************************************/ +void halAddTimer(Timer_t **head, Timer_t *new, uint32_t sysTime) +{ + if (!*head) + { + *head = new; + return; + } + + Timer_t *it, *prev = NULL; + for (it = *head; it; it = it->service.next) + { + uint32_t remain = it->service.sysTimeLabel + it->interval - sysTime; + if ((remain < INT32_MAX) && (remain >= new->interval)) + break; + prev = it; + } + if (it == *head) + { + new->service.next = *head; + *head = new; + } + else + { + prev->service.next = new; + new->service.next = it; + } +} + +/****************************************************************************** +Removes timer from the timers list. +Parameters: + head - address of pointer to head of the timers list. + prev - address of the timer before the timer that must be removed from the list. + p - address of timer that must be removed from the list. +Returns: + pointer to next cell or pointer to head if deleting is head +******************************************************************************/ +Timer_t* halRemoveTimer(Timer_t **head, Timer_t *prev, Timer_t *p) +{ + Timer_t *t; + + if (p == *head) + {// removing first element of list + t = p->service.next; + p->service.next = 0; + *head = t; + return *head; + } + else + { + prev->service.next = p->service.next; + p->service.next = 0; + return prev->service.next; + } +} + +/****************************************************************************** +The search of the timer in the timers list before one. +Parameters: + head - address of pointer to head of the timers list. +Returns: + pointer to saerching timer +******************************************************************************/ +Timer_t *halFindPrevTimer(Timer_t **head, Timer_t *p) +{ + Timer_t *t = *head; + + for (; t ;) + { + if (t->service.next == p) + return t; + t = t->service.next; + } + return NULL; +} +//eof timer.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c new file mode 100644 index 00000000..53a63927 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c @@ -0,0 +1,1061 @@ +/**************************************************************************//** +\file usart.c + +\brief USART implementation. Asynchronous mode. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 29/05/07 E. Ivanov - Created + 18/02/09 A. Luzhetsky - Corretced. +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define HANDLERS_GET(A, I) memcpy_P(A, &halUsartHandlers[I], sizeof(HalUsartTask_t)) +/** \brief Amount of reserved bytes in received buffer. Some clients (PC Windows for example) + send few more bytes after CTS setting, so we need to reserve some space for them. + Reserved space = Buffer Size / 2^BUFFER_RESERV. */ +#define BUFFER_RESERV 1 +#define USART_HW_CONTROLLER_TIMER_PERIOD 10 +#if defined(_USE_USART_ERROR_EVENT_) + #define HAL_BM_FRAME_ERROR (1 << 4) + #define HAL_BM_DATA_OVERRUN (1 << 3) + #define HAL_BM_PARITY_ERROR (1 << 2) +#endif +#if NUM_USART_CHANNELS == 0 + #error 'USART channels is not alowed.' +#endif + +/****************************************************************************** + Types definition section +******************************************************************************/ +/**************************************************************************//** + \brief HAL USART tasks bit mask. +******************************************************************************/ +typedef volatile uint8_t HalUsartTaskBitMask_t; + +/**************************************************************************//** + \brief HAL USART task type declaration. +******************************************************************************/ +typedef void (* HalUsartTask_t)(void); + +/****************************************************************************** + Global functions prototypes section +******************************************************************************/ +void halSigUsartHandler(void); +void halSetUsartConfig(HAL_UsartDescriptor_t *usartmode); +void halPostUsartTask(HalUsartTaskId_t taskId); +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + void hwControlPinsPollCallback(void); +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +/****************************************************************************** + Static function prototypes section +******************************************************************************/ +#if defined(HAL_USE_USART_CHANNEL_0) + static void halUsartTaskUsart0Dre(void); + static void halUsartTaskUsart0Txc(void); + static void halUsartTaskUsart0Rxc(void); + #if defined(_USE_USART_ERROR_EVENT_) + static void halUsartTaskUsart0Err(void); + #endif +#endif + +#if defined(HAL_USE_USART_CHANNEL_1) + static void halUsartTaskUsart1Dre(void); + static void halUsartTaskUsart1Txc(void); + static void halUsartTaskUsart1Rxc(void); + #if defined(_USE_USART_ERROR_EVENT_) + static void halUsartTaskUsart1Err(void); + #endif +#endif + +static void halUsartHwController(UsartChannel_t tty); +static void halSigUsartReceptionComplete(UsartChannel_t tty); +static void halSetUsartClockPinDirection(HAL_UsartDescriptor_t *descriptor); + +/****************************************************************************** + Static variables section +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + static HAL_AppTimer_t halUsartAppTimer; +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT +HAL_UsartDescriptor_t *halPointDescrip[NUM_USART_CHANNELS] = +{ + #if defined(HAL_USE_USART_CHANNEL_0) + NULL, + #endif + #if defined(HAL_USE_USART_CHANNEL_1) + NULL + #endif +}; +static volatile HalUsartTaskBitMask_t halUsartTaskBitMask = 0; // HAL USART tasks' bit mask. +static const HalUsartTask_t PROGMEM_DECLARE(halUsartHandlers[HAL_USART_TASKS_NUMBER]) = +{ + #if defined(HAL_USE_USART_CHANNEL_0) + halUsartTaskUsart0Dre, + halUsartTaskUsart0Txc, + halUsartTaskUsart0Rxc, + #if defined(_USE_USART_ERROR_EVENT_) + halUsartTaskUsart0Err, + #endif + #endif + + #if defined(HAL_USE_USART_CHANNEL_1) + halUsartTaskUsart1Dre, + halUsartTaskUsart1Txc, + halUsartTaskUsart1Rxc, + #if defined(_USE_USART_ERROR_EVENT_) + halUsartTaskUsart1Err, + #endif + #endif +}; // List Of possible HAL USART tasks. + +/****************************************************************************** + DTR service +******************************************************************************/ +volatile bool halEnableDtrWakeUp = false; +void (* dtrWakeUpCallback)(void) = NULL; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief HAL USART task. Exact action depends on USART internal task. +******************************************************************************/ +void halSigUsartHandler(void) +{ + HalUsartTask_t handler; + HalUsartTaskBitMask_t mask = 1; + HalUsartTaskId_t index = 0; + + for ( ; index < HAL_USART_TASKS_NUMBER; index++, mask <<= 1) + { + if (halUsartTaskBitMask & mask) + { + ATOMIC_SECTION_ENTER + halUsartTaskBitMask ^= mask; + ATOMIC_SECTION_LEAVE + HANDLERS_GET(&handler, index); + handler(); + } + } +} + +/**************************************************************************//** +\brief Posts specific USART task. + +\param[in] + taskId - unique identifier of the task to be posted. +******************************************************************************/ +void halPostUsartTask(HalUsartTaskId_t taskId) +{ + halUsartTaskBitMask |= (HalUsartTaskBitMask_t)1 << taskId; + halPostTask2(HAL_TASK_USART); +} + +/**************************************************************************//** +\brief Puts the byte received to the cyclic buffer. + +\param[in] + tty - channel number. +\param[in] + data - data to put. +******************************************************************************/ +void halUsartRxBufferFiller(UsartChannel_t tty, uint8_t data) +{ + uint16_t old; + uint8_t i; + HalUsartService_t *halUsartControl; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + {// abnormal + halDisableUsartRxcInterrupt(tty); // disable usart + return; + } + + if (halPointDescrip[i]->flowControl & USART_SPI_WRITE_MODE) + return; + + if (halPointDescrip[i]->flowControl & USART_SPI_READ_MODE) + { // For spi mode. + *(uint8_t*)(halPointDescrip[i]->rxBuffer) = data; + halPointDescrip[i]->rxBuffer++; + return; + } // For spi mode. + + halUsartControl = &halPointDescrip[i]->service; + if (NULL != halPointDescrip[i]->rxBuffer) + { + old = halUsartControl->rxPointOfWrite; + + if (++halUsartControl->rxPointOfWrite == halPointDescrip[i]->rxBufferLength) + halUsartControl->rxPointOfWrite = 0; + + if (halUsartControl->rxPointOfWrite == halUsartControl->rxPointOfRead) + { // Buffer full. + halUsartControl->rxPointOfWrite = old; + return; + } // Buffer full. + + halPointDescrip[i]->rxBuffer[old] = data; + halUsartControl->rxBytesInBuffer++; + +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if ((halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE) && (HW_CONTROL_PINS_PORT_ASSIGNMENT == halPointDescrip[i]->tty)) + { + if (halUsartControl->rxBytesInBuffer > (halPointDescrip[i]->rxBufferLength >> BUFFER_RESERV)) + GPIO_USART_CTS_set();// CTS_ON + } +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + } +} + +#if defined(_USE_USART_ERROR_EVENT_) +/**************************************************************************//** +\brief Save status register for analyzing of the error reason. + +\param[in] + tty - channel number. +\param[in] + status - usart status register. +******************************************************************************/ +void halUsartSaveErrorReason(UsartChannel_t tty, uint8_t status) +{ + HalUsartService_t *halUsartControl; + uint8_t i; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + {// abnormal + halDisableUsartRxcInterrupt(tty); // disable usart + return; + } + + halUsartControl = &halPointDescrip[i]->service; + halUsartControl->errorReason = status; +} +#endif + +/**************************************************************************//** +\brief Registers uasrt's event handlers. Performs configuration +of usart registers. Performs configuration of RTS, CTS and DTR pins. + +\param[in] + descriptor - pointer to HAL_UsartDescriptor_t structure + +\return + Returns positive usart descriptor on success or -1 in cases: \n + - bad usart channel. \n + - unsupported parameters. \n + - the channel was already opened. \n + - there are not enough resources. \n +******************************************************************************/ +int HAL_OpenUsart(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; // Descriptor index + + if (NULL == descriptor) + return -1; + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if ((descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE) && + (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty)) + return -1; // Hardware control cannot be used for this channel. +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (NULL != halPointDescrip[i]) + return -1; // Channel is already opened. + + halPointDescrip[i] = descriptor; +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if (HW_CONTROL_PINS_PORT_ASSIGNMENT == descriptor->tty) + { + if (descriptor->flowControl & USART_DTR_CONTROL) + GPIO_USART_DTR_make_in(); + if (descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE) + { + GPIO_USART_CTS_make_out(); + GPIO_USART_RTS_make_in(); + if (NULL == descriptor->rxBuffer) + GPIO_USART_CTS_set(); // CTS_ON + else + GPIO_USART_CTS_clr(); // CTS_OFF + } + } +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + if (USART_MODE_SYNC == descriptor->mode) + halSetUsartClockPinDirection(descriptor); + + descriptor->service.txPointOfRead = 0; + descriptor->service.txPointOfWrite = 0; + if (NULL == descriptor->rxBuffer) + descriptor->rxBufferLength = 0; + if (NULL == descriptor->txBuffer) + descriptor->txBufferLength = 0; + descriptor->service.rxPointOfRead = 0; + descriptor->service.rxPointOfWrite = 0; + descriptor->service.usartShiftRegisterEmpty = 1; + + halSetUsartConfig(descriptor); + + return descriptor->tty; +} + +/**************************************************************************//** +\brief Frees the usart channel and pins, if hardware flow control was used. + +\param[in] + descriptor - the usart descriptor. +\return + 0 on success, \n + -1 if bad descriptor or channel is already closed. +******************************************************************************/ +int HAL_CloseUsart(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + + if (NULL == descriptor) + return -1; + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (NULL == halPointDescrip[i]) + return -1; // Channel is already closed. + + halCloseUsart(halPointDescrip[i]->tty); +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if (halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE) + GPIO_USART_CTS_make_in(); +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + if (USART_MODE_SYNC == halPointDescrip[i]->mode) + { + halPointDescrip[i]->syncMode = USART_CLK_MODE_SLAVE; + halSetUsartClockPinDirection(halPointDescrip[i]); + } + halPointDescrip[i] = NULL; + + return 0; +} + +/**************************************************************************//** +\brief Controls RTS and DTR the pins and makes decision if the usart can transmit + byte. + +\param[in] + tty - channel number. +******************************************************************************/ +static void halUsartHwController(UsartChannel_t tty) +{ + uint8_t i; + HalUsartService_t *halUsartControl; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + return; // Port closed. + + halUsartControl = &halPointDescrip[i]->service; +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if (HW_CONTROL_PINS_PORT_ASSIGNMENT == tty) + { + uint8_t hw1 = 0; + uint8_t hw2 = 0; + + if (halPointDescrip[i]->flowControl & USART_DTR_CONTROL) + hw1 = GPIO_USART_DTR_read(); + + if (halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE) + hw2 = GPIO_USART_RTS_read(); + + if (hw1 || hw2) + { + halUsartAppTimer.interval = USART_HW_CONTROLLER_TIMER_PERIOD; + halUsartAppTimer.mode = TIMER_ONE_SHOT_MODE; + halUsartAppTimer.callback = hwControlPinsPollCallback; + HAL_StartAppTimer(&halUsartAppTimer); + return; + } + } +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + uint16_t poW; + uint16_t poR; + + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + poW = halUsartControl->txPointOfWrite; + poR = halUsartControl->txPointOfRead; + END_MEASURE(HAL_USART_HW_CONTROLLER_LIMIT) + ATOMIC_SECTION_LEAVE + + if (poW != poR) + { + halSendUsartByte(tty, halPointDescrip[i]->txBuffer[poR++]); + if (poR == halPointDescrip[i]->txBufferLength) + poR = 0; + halEnableUsartDremInterrupt(tty); + + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + halUsartControl->txPointOfRead = poR; + END_MEASURE(HAL_USART_HW_CONTROLLER_LIMIT) + ATOMIC_SECTION_LEAVE + + } + else + { + // data register empty interrupt was disabled + halEnableUsartTxcInterrupt(tty);// TX Complete interrupt enable + } +} + +/**************************************************************************//** +\brief Writes a number of bytes to a usart channel. +txCallback function will be used to notify when the transmission is finished. +If hardware flow control is used for transmitting then RTS and DTR pins will +be tested during transmission. + +\param[in] + descriptor - pointer to HAL_UsartDescriptor_t structure; + +\param[in] + buffer - pointer to the application data buffer; + +\param[in] + length - number of bytes to transfer; + +\return + -1 - bad descriptor; \n + Number of bytes placed to the buffer - success. +******************************************************************************/ +int HAL_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + uint8_t i; + uint16_t poW; + uint16_t poR; + uint16_t old; + uint16_t wasWrote = 0; + bool needStartTrmt = false; + HalUsartService_t *halUsartControl; + + if (NULL == descriptor) + return -1; + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + if (!buffer || !length) + return -1; + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + halUsartControl = &descriptor->service; + if (0 == descriptor->txBufferLength) + { // Callback mode + if (halUsartControl->txPointOfWrite != halUsartControl->txPointOfRead) + return -1; // there is unsent data + descriptor->txBuffer = buffer; + halUsartControl->txPointOfWrite = length; + halUsartControl->txPointOfRead = 0; + needStartTrmt = true; + wasWrote = length; + } // Callback mode. + else + { // Polling mode. + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + poW = halUsartControl->txPointOfWrite; + poR = halUsartControl->txPointOfRead; + END_MEASURE(HALATOM_WRITE_USART_TIME_LIMIT) + ATOMIC_SECTION_LEAVE + + if (poW == poR) + needStartTrmt = true; // Buffer empty. + + while (wasWrote < length) + { + old = poW; + + if (++poW == descriptor->txBufferLength) + poW = 0; + + if (poW == poR) + { // Buffer full. + poW = old; + break; + } // Buffer full. + + descriptor->txBuffer[old] = buffer[wasWrote++]; + } + + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + halUsartControl->txPointOfWrite = poW; + END_MEASURE(HALATOM_WRITE_USART_TIME_LIMIT) + ATOMIC_SECTION_LEAVE + } // Polling mode + + if (needStartTrmt) + { + halUsartControl->usartShiftRegisterEmpty = 0; // Buffer and shift register is full + // Enable interrupt. Transaction will be launched in the callback. + halEnableUsartDremInterrupt(descriptor->tty); + } + + return wasWrote; +} + +/*************************************************************************//** +\brief Reads length bytes from usart and places ones to buffer. + +\param[in] + descriptor - usart descriptor; +\param[out] + buffer - pointer to a application buffer; +\param[in] + length - the number of bytes which should be placed to buffer + +\return + -1 - bad descriptor, bad number to read or number of bytes that \n + were placed to buffer. +*****************************************************************************/ +int HAL_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length) +{ + uint8_t i = 0; + uint16_t wasRead = 0; + uint16_t poW; + uint16_t poR; + HalUsartService_t *halUsartControl; +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + uint16_t number; +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + if (NULL == descriptor) + return -1; + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + if (!buffer || !length) + return -1; + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + halUsartControl = &halPointDescrip[i]->service; + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + poW = halUsartControl->rxPointOfWrite; + poR = halUsartControl->rxPointOfRead; + END_MEASURE(HALATOM_READ_USART_TIME_LIMIT) + ATOMIC_SECTION_LEAVE + + while ((poR != poW) && (wasRead < length)) + { + buffer[wasRead] = descriptor->rxBuffer[poR]; + if (++poR == descriptor->rxBufferLength) + poR = 0; + wasRead++; + } + + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + halUsartControl->rxPointOfRead = poR; + halUsartControl->rxBytesInBuffer -= wasRead; +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + number = halUsartControl->rxBytesInBuffer; +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + END_MEASURE(HALATOM_READ_USART_TIME_LIMIT) + ATOMIC_SECTION_LEAVE + +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT + if ((HW_CONTROL_PINS_PORT_ASSIGNMENT == descriptor->tty) && (descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE)) + if (number <= (descriptor->rxBufferLength >> BUFFER_RESERV)) + GPIO_USART_CTS_clr(); +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + + return wasRead; +} + +/**************************************************************************//** +\brief Forbids to the host data transmiting. Only HW_CONTROL_PINS_PORT_ASSIGNMENT + port can be used for hardware flow control. + +\param[in] + descriptor - usart descriptor. + +\return + -1 - bad descriptor, bad usart, unsupported mode; + 0 - on success. +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT +int HAL_OnUsartCts(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + + if (NULL == descriptor) + return -1; + + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty) + return -1; + + GPIO_USART_CTS_set();// CTS_ON + + return 0; +} +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +/**************************************************************************//** +\brief Allows to transfer a host data. Only HW_CONTROL_PINS_PORT_ASSIGNMENT +can be used for hardware flow control. + +\param[in] + descriptor - usart descriptor. + +\return + -1 - bad descriptor, bad usart, unsupported mode; + 0 - on success. +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT +int HAL_OffUsartCts(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + + if (NULL == descriptor) + return -1; + + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty) + return -1; + + GPIO_USART_CTS_clr(); // CTS_OFF + + return 0; +} +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +/**************************************************************************//** +\brief Fills UsartHardwareControl_t variable by potential of RTS pin. Only + HW_CONTROL_PINS_PORT_ASSIGNMENT can be used for hardware flow control. + +\param[in] + descriptor - usart descriptor. +\return + -1 - bad descriptor, bad usart, unsupported mode; + 0 - on success. +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT +int HAL_ReadUsartRts(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + + if (NULL == descriptor) + return -1; + + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty) + return -1; + + return GPIO_USART_RTS_read(); +} +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +/**************************************************************************//** +\brief Fills UsartHardwareControl_t variable by potential of DTR pin. Only + HW_CONTROL_PINS_PORT_ASSIGNMENT can be used for hardware flow control. + +\param[in] + descriptor - usart descriptor. +\return + -1 - bad descriptor, bad usart, unsupported mode; + 0 - on success. +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT +int HAL_ReadUsartDtr(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + + if (NULL == descriptor) + return -1; + + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty) + return -1; + + return GPIO_USART_DTR_read(); +} +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +// Interrupt handlers +/**************************************************************************//** +\brief Hardware Control pins polling timer callback. +******************************************************************************/ +#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT +void hwControlPinsPollCallback(void) +{ + halUsartHwController(HW_CONTROL_PINS_PORT_ASSIGNMENT); +} +#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT + +/**************************************************************************//** +\brief Transmission complete interrupt handler. + +\param[in] + tty - USART channel identifier. +******************************************************************************/ +void halSigUsartTransmissionComplete(UsartChannel_t tty) +{ + uint8_t i; + HalUsartService_t *halUsartControl; + uint16_t poW; + uint16_t poR; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + { + assert(false, USARTC_HALSIGUSARTTRANSMISSIONCOMPLETE_0); + return; // Descriptor with "tty" channel is not found. + } + + halUsartControl = &halPointDescrip[i]->service; + + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + poW = halUsartControl->txPointOfWrite; + poR = halUsartControl->txPointOfRead; + END_MEASURE(HAL_USART_TRANS_COMPLETE_LIMIT) + ATOMIC_SECTION_LEAVE + + if (poW == poR) + halUsartControl->usartShiftRegisterEmpty = 1; // Buffer is empty, shift register is empty too. + + if (0 == halPointDescrip[i]->txBufferLength) + halPointDescrip[i]->txBuffer = NULL; // nulling pointer for callback mode + + if (NULL != halPointDescrip[i]->txCallback) + halPointDescrip[i]->txCallback(); +} + +/**************************************************************************//** +\brief Reception complete interrupt handler. + +\param[in] + tty - USART channel identifier. +******************************************************************************/ +static void halSigUsartReceptionComplete(UsartChannel_t tty) +{ + uint8_t i; + HalUsartService_t *halUsartControl; + uint16_t number; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + { + assert(false, USARTC_HALSIGUSARTRECEPTIONCOMPLETE_0); + return; // Descriptor with "tty" channel is not found. + } + + if (halPointDescrip[i]->flowControl & (USART_SPI_READ_MODE | USART_SPI_WRITE_MODE)) + return; // for spi mode + + halUsartControl = &halPointDescrip[i]->service; + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + number = halUsartControl->rxBytesInBuffer; + END_MEASURE(HALATOM_USART_RX_COMPLETE_TIME_LIMIT) + ATOMIC_SECTION_LEAVE + + if (number) + if (NULL != halPointDescrip[i]->rxCallback) + halPointDescrip[i]->rxCallback(number); +} + +#if defined(_USE_USART_ERROR_EVENT_) +/**************************************************************************//** +\brief Error occurred action handler. + +\param[in] + tty - USART channel identifier. +******************************************************************************/ +static void halSigUsartErrorOccurred(UsartChannel_t tty) +{ + uint8_t i; + HalUsartService_t *halUsartControl; + UsartErrorReason_t errReason = FRAME_ERROR; + + i = HAL_GET_INDEX_BY_CHANNEL(tty); + if (NULL == halPointDescrip[i]) + { + assert(false, USARTC_HALSIGUSARTERROROCCURED_0); + return; // Descriptor with "tty" channel is not found. + } + + halUsartControl = &halPointDescrip[i]->service; + if (halUsartControl->errorReason & HAL_BM_FRAME_ERROR) + errReason = FRAME_ERROR; + else if (halUsartControl->errorReason & HAL_BM_DATA_OVERRUN) + errReason = DATA_OVERRUN; + else if (halUsartControl->errorReason & HAL_BM_PARITY_ERROR) + errReason = PARITY_ERROR; + else + { + assert(false, USARTC_HALUNKNOWNERRORREASON_0); + } + + if (NULL != halPointDescrip[i]->errCallback) + halPointDescrip[i]->errCallback(errReason); +} +#endif + +/**************************************************************************//** +\brief Enables DTR wake up. + +\param[in] callback - callback method pointer. +******************************************************************************/ +void HAL_EnableDtrWakeUp(void (* callback)(void)) +{ + dtrWakeUpCallback = callback; + halEnableDtrWakeUp = true; +} + +/**************************************************************************//** +\brief Disables DTR wake up. +******************************************************************************/ +void HAL_DisableDtrWakeUp(void) +{ + halEnableDtrWakeUp = false; +} + +/**************************************************************************//** +\brief Checks the status of tx buffer. + +\param[in] + descriptor - pointer to HAL_UsartDescriptor_t structure; + +\return + -1 - bad descriptor, no tx buffer; \n + 1 - tx buffer is empty; \n + 0 - tx buffer is not empty; +******************************************************************************/ +int HAL_IsTxEmpty(HAL_UsartDescriptor_t *descriptor) +{ + uint8_t i; + HalUsartService_t *halUsartControl; + uint16_t poW; + uint16_t poR; + + if (NULL == descriptor) + return -1; + if (false == halIsUsartChannelCorrect(descriptor->tty)) + return -1; + i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty); + if (descriptor != halPointDescrip[i]) + return -1; // Channel is not opened. + + halUsartControl = &halPointDescrip[i]->service; + ATOMIC_SECTION_ENTER + BEGIN_MEASURE + poW = halUsartControl->txPointOfWrite; + poR = halUsartControl->txPointOfRead; + END_MEASURE(HAL_USART_TX_EMPTY_LIMIT) + ATOMIC_SECTION_LEAVE + if (poW == poR) + return halUsartControl->usartShiftRegisterEmpty; + return 0; +} + +/**************************************************************************//** +\brief Checks the channel number. + +\param[in] + channel - channel to be verified. + +\return + true if channel is possible, \n + false otherwise. +******************************************************************************/ +bool halIsUsartChannelCorrect(UsartChannel_t channel) +{ + switch (channel) + { +#ifdef USART_CHANNEL_0 + case USART_CHANNEL_0: +#endif // USART_CHANNEL_0 +#ifdef USART_CHANNEL_1 + case USART_CHANNEL_1: +#endif // USART_CHANNEL_0 +#if defined(USART_CHANNEL_0) || defined(USART_CHANNEL_1) + return true; +#endif + default: + return false; + } +} + +/**************************************************************************//** +\brief Set clock pin direction for synchronous mode. + +\param[in] + descriptor - pointer to usart channel descriptor. +******************************************************************************/ +static void halSetUsartClockPinDirection(HAL_UsartDescriptor_t *descriptor) +{ + if (USART_CLK_MODE_MASTER == descriptor->syncMode) + { + switch (descriptor->tty) + { +#ifdef USART_CHANNEL_0 + case USART_CHANNEL_0: + GPIO_USART0_EXTCLK_make_out(); + break; +#endif // USART_CHANNEL_0 +#ifdef USART_CHANNEL_1 + case USART_CHANNEL_1: + GPIO_USART1_EXTCLK_make_out(); + break; +#endif // USART_CHANNEL_1 + default: + break; + } + } + else + { + switch (descriptor->tty) + { +#ifdef USART_CHANNEL_0 + case USART_CHANNEL_0: + GPIO_USART0_EXTCLK_make_in(); + GPIO_USART0_EXTCLK_make_pullup(); + break; +#endif // USART_CHANNEL_0 +#ifdef USART_CHANNEL_1 + case USART_CHANNEL_1: + GPIO_USART1_EXTCLK_make_in(); + GPIO_USART1_EXTCLK_make_pullup(); + break; +#endif // USART_CHANNEL_1 + default: + break; + } + } +} + +#if defined(HAL_USE_USART_CHANNEL_0) +/**************************************************************************//** +\brief Wrapper for data empty handler for usart channel 0 +******************************************************************************/ +static void halUsartTaskUsart0Dre(void) +{ + halUsartHwController(USART_CHANNEL_0); +} + +/**************************************************************************//** +\brief Wrapper for transmit complete handler for usart channel 0 +******************************************************************************/ +static void halUsartTaskUsart0Txc(void) +{ + halSigUsartTransmissionComplete(USART_CHANNEL_0); +} + +/**************************************************************************//** +\brief Wrapper for receive complete handler for usart channel 0 +******************************************************************************/ +static void halUsartTaskUsart0Rxc(void) +{ + halSigUsartReceptionComplete(USART_CHANNEL_0); +} + +#if defined(_USE_USART_ERROR_EVENT_) +/**************************************************************************//** +\brief Wrapper for error occurred handler for usart channel 0 +******************************************************************************/ +static void halUsartTaskUsart0Err(void) +{ + halSigUsartErrorOccurred(USART_CHANNEL_0); +} +#endif // defined(_USE_USART_ERROR_EVENT_) +#endif // defined(HAL_USE_USART_CHANNEL_0) + +#if defined(HAL_USE_USART_CHANNEL_1) +/**************************************************************************//** +\brief Wrapper for data empty handler for usart channel 1 +******************************************************************************/ +static void halUsartTaskUsart1Dre(void) +{ + halUsartHwController(USART_CHANNEL_1); +} + +/**************************************************************************//** +\brief Wrapper for transmit complete handler for usart channel 1 +******************************************************************************/ +static void halUsartTaskUsart1Txc(void) +{ + halSigUsartTransmissionComplete(USART_CHANNEL_1); +} + +/**************************************************************************//** +\brief Wrapper for receive complete handler for usart channel 0 +******************************************************************************/ +static void halUsartTaskUsart1Rxc(void) +{ + halSigUsartReceptionComplete(USART_CHANNEL_1); +} + +#if defined(_USE_USART_ERROR_EVENT_) +/**************************************************************************//** +\brief Wrapper for error occurred handler for usart channel 1 +******************************************************************************/ +static void halUsartTaskUsart1Err(void) +{ + halSigUsartErrorOccurred(USART_CHANNEL_1); +} +#endif // defined(_USE_USART_ERROR_EVENT_) +#endif // defined(HAL_USE_USART_CHANNEL_1) +//eof usart.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usb.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usb.c new file mode 100644 index 00000000..b164f1dc --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usb.c @@ -0,0 +1,435 @@ +/**************************************************************************//** + \file usb.c + + \brief Implementation of usb hardware independent module. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 17/07/08 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + External global variables section +******************************************************************************/ +// user's request handler +extern void (* sendReqToUpper)(uint8_t *req); +// Holds the internal state for each endpoint of the UDP +extern UsbEndpoint_t endpoints[USB_END_POINTS_NUMBER]; +// Device current state +extern volatile uint8_t deviceState; +// Previous device current state +extern volatile uint8_t previousDeviceState; +// pointer to request memory. Memory allocate by user. +extern uint8_t *requestMemory; + +/****************************************************************************** + Global variables section +******************************************************************************/ +void (* resumeCallback)(void) = NULL; +void (* suspendCallback)(void) = NULL; +void (* endOfBusResetCallback)(void) = NULL; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** + Registers user's end of bus reset handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterEndOfBusResetHandler(void (* f)(void)) +{ + endOfBusResetCallback = f; +} + +/****************************************************************************** + Registers user's resume handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterResumeHandler(void (* f)(void)) +{ + resumeCallback = f; +} + +/****************************************************************************** + Registers user's suspend handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterSuspendHandler(void (* f)(void)) +{ + suspendCallback = f; +} + +/****************************************************************************** + Registers user's request handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterRequestHandler(void (* f)(uint8_t *req)) +{ + sendReqToUpper = f; +} + +/****************************************************************************** +Configures an endpoint according to its Endpoint Descriptor. + +Parameters: + descriptor - Pointer to an Endpoint descriptor. +******************************************************************************/ +void HAL_ConfigureEndpoint(HAL_UsbEndPointDescptr_t *descriptor) +{ + UsbEndpoint_t *endpoint; + uint8_t eptnum; + uint8_t type; + HAL_UsbEndPointDirect_t direction; + + // NULL descriptor -> Control endpoint 0 + if (NULL == descriptor) + { + eptnum = USB_END_POINT_0; + endpoint = &(endpoints[USB_END_POINT_0]); + type = EP_CONTROL; + direction = EP_OUT; + endpoint->size = UDP_ENDPOINTS_MAXPACKETSIZE(USB_END_POINT_0); + } + else + { + eptnum = descriptor->bEndpointAddress & 0x0F; + endpoint = &(endpoints[eptnum]); + type = descriptor->bmAttributes & 0x03; + if (descriptor->bEndpointAddress & 0x80) + direction = EP_IN; + else + direction = EP_OUT; + endpoint->size = descriptor->wMaxPacketSize; + } + + // Abort the current transfer is the endpoint was configured and in + // Write or Read state + if ((UDP_ENDPOINT_RECEIVING == endpoint->state) || (UDP_ENDPOINT_SENDING == endpoint->state)) + halEndOfTransfer(eptnum, STATUS_RESET); + + endpoint->state = UDP_ENDPOINT_IDLE; + halConfigureEndpoint(eptnum, type, direction); +} + +/****************************************************************************** +Sends data through a USB endpoint. Sets up the transfer descriptor, +writes one or two data payloads (depending on the number of FIFO bank +for the endpoint) and then starts the actual transfer. The operation is +complete when all the data has been sent. + +*If the size of the buffer is greater than the size of the endpoint +(or twice the size if the endpoint has two FIFO banks), then the buffer +must be kept allocated until the transfer is finished*. This means that +it is not possible to declare it on the stack (i.e. as a local variable +of a function which returns after starting a transfer). + +Parameters: + eptnum - Endpoint number. + data - Pointer to a buffer with the data to send. + size - Size of the data buffer. + callback - Optional callback function to invoke when the transfer is complete. + argument - Optional argument to the callback function. + +Returns: + STATUS_SUCCESS if the transfer has been started; otherwise, the + corresponding error status code. +******************************************************************************/ +uint8_t HAL_UsbWrite(uint8_t eptnum, void *data, uint32_t size, TransferCallback_t callback, void *argument) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + UsbTransfer_t *transfer = &(endpoint->transfer); + + // Check that the endpoint is in Idle state + if (UDP_ENDPOINT_IDLE != endpoint->state) + return STATUS_BUSY; + + // Setup the transfer descriptor + transfer->data = (void *) data; + transfer->remaining = size; + transfer->buffered = 0; + transfer->transferred = 0; + transfer->callback = callback; + transfer->argument = argument; + + // Send the first packet + endpoint->state = UDP_ENDPOINT_SENDING; + halStartUsbWrite(eptnum); + + // Enable interrupt on endpoint + halEnableEndPointTxInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Reads incoming data on an USB endpoint This methods sets the transfer +descriptor and activate the endpoint interrupt. The actual transfer is +then carried out by the endpoint interrupt handler. The Read operation +finishes either when the buffer is full, or a short packet (inferior to +endpoint maximum size) is received. + +*The buffer must be kept allocated until the transfer is finished*. + +Parameters: + eptnum - Endpoint number. + data - Pointer to a data buffer. + size - Size of the data buffer in bytes. + callback - Optional end-of-transfer callback function. + argument - Optional argument to the callback function. + +Returns: + STATUS_SUCCESS if the read operation has been started; otherwise, + the corresponding error code. +******************************************************************************/ +uint8_t HAL_UsbRead(uint8_t eptnum, void *data, uint32_t size, TransferCallback_t callback, void *argument) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + UsbTransfer_t *transfer = &(endpoint->transfer); + + if (NULL == data) + return STATUS_ABORTED; + + // Return if the endpoint is not in IDLE state + if (UDP_ENDPOINT_IDLE != endpoint->state) + return STATUS_BUSY; + + // Endpoint enters Receiving state + endpoint->state = UDP_ENDPOINT_RECEIVING; + + // Set the transfer descriptor + transfer->data = data; + transfer->remaining = size; + transfer->buffered = 0; + transfer->transferred = 0; + transfer->callback = callback; + transfer->argument = argument; + + // Enable interrupt on endpoint + halEnableEndPointRxInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Sets the HALT feature on the given endpoint (if not already in this state). + +Parameters: + eptnum - Endpoint number. +******************************************************************************/ +void HAL_Halt(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check that endpoint is enabled and not already in Halt state + if ((UDP_ENDPOINT_DISABLED != endpoint->state) && (UDP_ENDPOINT_HALTED != endpoint->state)) + { + // Abort the current transfer if necessary + halEndOfTransfer(eptnum, STATUS_ABORTED); + + halEndpointHaltState(eptnum); + + // Enable the endpoint interrupt + halEnableEndPointStallInterrupt(eptnum); + } +} + +/****************************************************************************** +Clears the Halt feature on the given endpoint. + +Parameters: + eptnum - Endpoint number. +******************************************************************************/ +void HAL_Unhalt(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check if the endpoint is enabled + if (UDP_ENDPOINT_DISABLED != endpoint->state) + { + // Return endpoint to Idle state + endpoint->state = UDP_ENDPOINT_IDLE; + + halEndpointUnHaltState(eptnum); + } +} + +/****************************************************************************** +Returns the current Halt status of an endpoint. + +Parameters: + eptnum - Endpoint number. + +Returns: + 1 - if the endpoint is currently halted; + 0 - otherwise. +******************************************************************************/ +uint8_t HAL_IsHalted(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + if (UDP_ENDPOINT_HALTED == endpoint->state) + return 1; + else + return 0; +} + +/****************************************************************************** +Causes the given endpoint to acknowledge the next packet it receives with +a STALL handshake. + +Parameters: + eptnum - Endpoint number. + +Returns: + STATUS_SUCCESS or STATUS_BUSY. +******************************************************************************/ +uint8_t HAL_Stall(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check that endpoint is in Idle state + if (UDP_ENDPOINT_IDLE != endpoint->state) + { + return STATUS_BUSY; + } + + halSendStallToHost(eptnum); + // Enable the endpoint interrupt + halEnableEndPointStallInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Sets the device address to the given value. + +Parameters: + address - New device address. +******************************************************************************/ +void HAL_SetAddress(uint8_t *address) +{ + halSetUsbAddress(*address); + // If the address is 0, the device returns to the Default state + if (*address) + deviceState = DEVICE_PREADDRESSED; + // If the address is non-zero, the device enters the Address state + else + deviceState = DEVICE_DEFAULT; +} + +/****************************************************************************** +Sets the current device configuration. + +Parameters: + cfgnum - Configuration number to set. +******************************************************************************/ +void HAL_SetConfiguration(uint8_t cfgnum) +{ + // If the configuration number if non-zero, the device enters the + // Configured state + if (cfgnum) + { + deviceState = DEVICE_CONFIGURED; + } + // If the configuration number is zero, the device goes back to the Address + // state + else + { + deviceState = DEVICE_ADDRESS; + // Abort all transfers + halDisableEndpoints(); + } +} + +/****************************************************************************** +Initializes the USB driver. + +Parameters: + reqMem - Memory for usb request. Memory allocate by user. +******************************************************************************/ +void HAL_UsbInit(uint8_t *reqMem) +{ + requestMemory = reqMem; + + // Reset endpoint structures + halResetEndpoints(); + + // Device is in the Attached state + deviceState = DEVICE_SUSPENDED; + previousDeviceState = DEVICE_POWERED; + halInitUsbDevice(); + halUsbInterrupt(); +} + +/****************************************************************************** +Returns the current state of the USB device. + +Returns: + Device current state. +******************************************************************************/ +uint8_t HAL_GetState(void) +{ + return deviceState; +} + +/****************************************************************************** +Endpoint interrupt handler. +******************************************************************************/ +void halEndPointHandler(void) +{ + halCommonEndpointHandler(); +} + +/****************************************************************************** +usb suspend interrupt handler. +******************************************************************************/ +void halSuspendHandler(void) +{ + if (NULL != suspendCallback) + suspendCallback(); +} + +/****************************************************************************** +usb resume interrupt handler. +******************************************************************************/ +void halResumeHandler(void) +{ + if (NULL != resumeCallback) + resumeCallback(); +} + +/****************************************************************************** +usb bus reset interrupt handler. +******************************************************************************/ +void halBusResetHandler(void) +{ + halEndOfBusResetHandler(); + if (NULL != endOfBusResetCallback) + endOfBusResetCallback(); +} + +// eof usb.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/w1.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/w1.c new file mode 100644 index 00000000..99b92d1a --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/w1.c @@ -0,0 +1,382 @@ +/**************************************************************************//** + \file w1.c + + \brief The implementation of the 1-wire interface. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 10/12/07 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define HAL_ROM_BYTE_LEN 8 +#define HAL_ROM_BIT_LEN 64 +#define HAL_W1_CRC_POLINOM 0x8C +#define HAL_SEARCH_ROM_CMD 0xF0 +#define HAL_SEARCH_ALRM_CMD 0xEC + +/****************************************************************************** + Prototypes section +******************************************************************************/ +/******************************************************************************* + 1-Wire search procedure for all devices discovering + Parameters: + cmd - ROM function command. + family - 8-bit family code. + data - pointer of SRAM where are stored the 8 bytes ROM + codes returned by the devices. + count - number of devices wish to find. + actCount - number of devices have been found. + Returns: + W1_SUCCESS_STATUS - if at least one device has been found. + W1_NO_DEVICE_STATUS - if there are no any devices presented + on the bus with specified family code. + W1_INVALID_CRC - if during searching invalid CRC has + been read and no devices with + spicified family code has been found. +*******************************************************************************/ +W1Status_t halCommSearchW1(uint8_t cmd, + uint8_t family, + uint8_t *data, + uint8_t count, + uint8_t *actCount); + +/******************************************************************************* + 1-Wire search procedure for one device discovering + Parameters: + cmd - ROM function command. + Returns: + W1_SUCCESS_STATUS - if device has been found, ROM number + in ROM_NO buffer. + W1_NO_DEVICE_STATUS - if device has not been found. + W1_INVALID_CRC - if during searching invalid CRC has + been read. +*******************************************************************************/ +W1Status_t halSearchW1(uint8_t cmd); + +/******************************************************************************* + Calculating 1-Wire 8-bit CRC + Parameters: + data - data buffer pointer. + length - data length. + Returns: + CRC value based on polynomial x^8 + x^5 + x^4 + 1 +*******************************************************************************/ +uint8_t halW1CRC(uint8_t *data, uint8_t length); + +/****************************************************************************** + Global variables section +******************************************************************************/ +// 8-byte buffer that contains the current ROM registration +// number discovered +static uint8_t ROM_NO[HAL_ROM_BYTE_LEN]; +// Bit index that identifies from which bit the next search +// discrepancy check should start +static uint8_t LastDiscrepancy; +// Flag to indicate previos search was the last device +static uint8_t LastDeviceFlag; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/******************************************************************************* + 1-Wire search procedure with search ROM command only + Parameters: + family - 8-bit family code. + data - pointer of SRAM where are stored the 8 bytes ROM + codes returned by the devices. + count - number of devices wish to find. + actCount - number of devices have been found. + Returns: + W1_SUCCESS_STATUS - if at least one device has been found. + W1_NO_DEVICE_STATUS - if there are no any devices presented + on the bus with specified family code. + W1_INVALID_CRC - if during searching invalid CRC has + been read and no devices with + spicified family code has been found. +*******************************************************************************/ +W1Status_t HAL_SearchW1Device(uint8_t family, + uint8_t *data, + uint8_t count, + uint8_t *actCount) +{ + return halCommSearchW1(HAL_SEARCH_ROM_CMD, family, data, count, actCount); +} + +/******************************************************************************* + 1-Wire search procedure with alarm search command only + Parameters: + family - 8-bit family code. + data - pointer of SRAM where are stored the 8 bytes ROM + codes returned by the devices. + count - number of devices wish to find. + actCount - number of devices have been found. + Returns: + W1_SUCCESS_STATUS - if at least one device has been found. + W1_NO_DEVICE_STATUS - if there are no any devices presented + on the bus with specified family code. + W1_INVALID_CRC - if during searching invalid CRC has + been read and no devices with + spicified family code has been found. +*******************************************************************************/ +W1Status_t HAL_AlarmSearchW1Device(uint8_t family, + uint8_t *data, + uint8_t count, + uint8_t *actCount) +{ + return halCommSearchW1(HAL_SEARCH_ALRM_CMD, family, data, count, actCount); +} + +/******************************************************************************* + 1-Wire search procedure for all devices discovering + Parameters: + cmd - ROM function command. + family - 8-bit family code. + data - pointer of SRAM where are stored the 8 bytes ROM + codes returned by the devices. + count - number of devices wish to find. + actCount - number of devices have been found. + Returns: + W1_SUCCESS_STATUS - if at least one device has been found. + W1_NO_DEVICE_STATUS - if there are no any devices presented + on the bus with specified family code. + W1_INVALID_CRC - if during searching invalid CRC has + been read and no devices with + spicified family code has been found. +*******************************************************************************/ +W1Status_t halCommSearchW1(uint8_t cmd, + uint8_t family, + uint8_t *data, + uint8_t count, + uint8_t *actCount) +{ + W1Status_t w1_result; + uint8_t i; + + // Reset the searh state + LastDiscrepancy = 0; + LastDeviceFlag = 0; + // Setup family code + if (W1_ANY_FAMILY != family) + { + ROM_NO[0] = family; + LastDiscrepancy = HAL_ROM_BIT_LEN + 1; + for (i = 1; i < HAL_ROM_BYTE_LEN; i++) ROM_NO[i] = 0; + } + i = 0; + // Discovering + do + { + w1_result = halSearchW1(cmd); + if (W1_SUCCESS_STATUS != w1_result) + break; + // There is some device with specified family code + if ((ROM_NO[0] == family) || (W1_ANY_FAMILY == family)) + { + *(uint64_t *)(data + 8 * i) = *(uint64_t *)ROM_NO; + i++; + } + else // There are not any devices with specified family code + { + w1_result = W1_NO_DEVICE_STATUS; + break; + } + } + while (!LastDeviceFlag && (i < count)); + + if (NULL != actCount) + *actCount = i; + + if (i != 0) + return W1_SUCCESS_STATUS; + else + return w1_result; +} + +/******************************************************************************* + 1-Wire search procedure for one device discovering + Parameters: + cmd - ROM function command. + Returns: + W1_SUCCESS_STATUS - if device has been found, ROM number + in ROM_NO buffer. + W1_NO_DEVICE_STATUS - if device has not been found. + W1_INVALID_CRC - if during searching invalid CRC has + been read. +*******************************************************************************/ +W1Status_t halSearchW1(uint8_t cmd) +{ + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number; + uint8_t id_bit, cmp_id_bit; + uint8_t rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + + // 1-Wire reset + ATOMIC_SECTION_ENTER + id_bit = halResetW1(); + ATOMIC_SECTION_LEAVE + if (W1_NO_DEVICE_STATUS == id_bit) + { + LastDiscrepancy = 0; + LastDeviceFlag = 0; + return W1_NO_DEVICE_STATUS; + } + + // issue the search command + ATOMIC_SECTION_ENTER + halWriteW1(cmd); + ATOMIC_SECTION_LEAVE + // search 64-bit uniqued registration number + do + { + // read a bit and its complement + ATOMIC_SECTION_ENTER + id_bit = halReadW1Bit(); + cmp_id_bit = halReadW1Bit(); + ATOMIC_SECTION_LEAVE + // check for no devices on 1-wire + if ((1 == id_bit) && (1 == cmp_id_bit)) + return W1_NO_DEVICE_STATUS; + + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + { + search_direction = id_bit; + // there is descepancy + } + else + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time (old branch) + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + // if equal to last pick 1, if not then pick 0 (new branch) + else + search_direction = (id_bit_number == LastDiscrepancy); + // if 0 was picked then record its position in LastZero + if (0 == search_direction) + last_zero = id_bit_number; + } + + if (1 == search_direction) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + ATOMIC_SECTION_ENTER + halWriteW1bit(search_direction); + ATOMIC_SECTION_LEAVE + id_bit_number++; + rom_byte_mask <<= 1; + + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } while (rom_byte_number < HAL_ROM_BYTE_LEN); + + // Invalid CRC + if (halW1CRC(ROM_NO, HAL_ROM_BYTE_LEN)) + return W1_INVALID_CRC; + + LastDiscrepancy = last_zero; + // check for last device + if (0 == LastDiscrepancy) + LastDeviceFlag = 1; + + return W1_SUCCESS_STATUS; +} + +/******************************************************************************* + Calculating 1-Wire 8-bit CRC + Parameters: + data - data buffer pointer. + length - data length. + Returns: + CRC value based on polynomial x^8 + x^5 + x^4 + 1 +*******************************************************************************/ +uint8_t halW1CRC(uint8_t *data, uint8_t length) +{ + uint8_t reg; + uint8_t b; + + for (reg = 0; length > 0; length--, data++) + { + for (b = 0; b < 8; b++) + { + if (((*data >> b) & 1) ^ (reg & 1)) + { + reg >>= 1; + reg ^= HAL_W1_CRC_POLINOM; + } + else + reg >>= 1; + } + } + return reg; +} + +/******************************************************************************* +Resets all devices connected to the bus. +Parameters: + none. +Returns: + 0 - there are some devices at the bus. + 1 - there are not any devices at the bus. +*******************************************************************************/ +uint8_t HAL_ResetW1(void) +{ + return halResetW1(); +}; + +/******************************************************************************* +Writes byte to the bus +Parameters: + value - byte to write. +Returns: + none. +*******************************************************************************/ +void HAL_WriteW1(uint8_t value) +{ + halWriteW1(value); +} + +/******************************************************************************* +Reads byte from the bus. +Parameters: + none. +Returns: + byte read from the bus. +*******************************************************************************/ +uint8_t HAL_ReadW1(void) +{ + return halReadW1(); +} + +// eof halW1.c -- cgit v1.2.3