hello world
Fork of lmic_MOTE_L152RC by
Diff: hal.cpp
- Revision:
- 11:671d85a0f15b
- Parent:
- 6:dfc048cda33f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hal.cpp Tue Feb 09 00:28:59 2016 +0000 @@ -0,0 +1,356 @@ +/* HAL for MOTE_L152RC */ + +#include "mbed.h" +#include "oslmic.h" +#include "debug.h" + +#define RADIO_MOSI PTD6 +#define RADIO_MISO PTD7 +#define RADIO_SCLK PTD5 +#define RADIO_NSS PTD4 +//#define RESET_PIN PTC1 /* *** TODO *** */ + +//#define RFSW1 PTC1 //NorAm_Mote RFSwitch_CNTR_1 *** TODO *** +//#define RFSW2 PTC1 //NorAm_Mote RFSwitch_CNTR_2 *** TODO *** + +static DigitalOut nss(PTD4); +static SPI spi(RADIO_MOSI, RADIO_MISO, RADIO_SCLK); // (mosi, miso, sclk) + +//static DigitalInOut rst(RESET_PIN); + +//DigitalOut rfsw1(RFSW1); +//DigitalOut rfsw2(RFSW2); + +//DigitalOut hdr_fem_csd(PTC1); /* *** TODO *** */ + +static InterruptIn dio0(PTC2); +static InterruptIn dio1(PTC4); /* *** TODO *** */ +static InterruptIn dio2(PTC3); + +//extern RTC_HandleTypeDef RtcHandle; +u4_t sleepTimeout; + +// HAL state +static struct { + int irqlevel; +} HAL; + +void radio_irq_handler (u1_t dio); + +static void dio0Irq( void ){ + radio_irq_handler( 0 ); +} +static void dio1Irq( void ){ + radio_irq_handler( 1 ); +} +static void dio2Irq( void ){ + radio_irq_handler( 2 ); +} + +void hal_disableIRQs() +{ + __disable_irq(); + HAL.irqlevel++; +} + +void hal_enableIRQs() +{ + if (--HAL.irqlevel == 0) { + __enable_irq(); + } +} + +void hal_failed () +{ + while (1) + asm("nop"); +} + +//static void rtc_wkup_irq(void) +//{ +// HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); +//} + +//void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) +//{ +// /* Clear Wake Up Flag */ +// __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); +//} + +/*void HAL_RCC_CCSCallback() +{ + for (;;) asm("nop"); +}*/ + + +volatile uint32_t /*rcc_cr_a, rcc_cr_b,*/ rcc_cr_c; +void hal_init (void) +{ + debugSW("hal_init enter\r\n"); + memset(&HAL, 0x00, sizeof(HAL)); + hal_disableIRQs(); + +#if USE_SMTC_RADIO_DRIVER + +#else + // configure input lines + dio0.mode(PullDown); + dio0.rise(dio0Irq); + dio0.enable_irq(); + dio1.mode(PullDown); + dio1.rise(dio1Irq); + dio1.enable_irq(); + dio2.mode(PullDown); + dio2.rise(dio2Irq); + dio2.enable_irq(); + // configure reset line +// rst.input(); + // configure spi +// spi.frequency(8000000); + spi.frequency(1000000); + spi.format(8, 0); + nss = 1; + //RFSwitch_CNTR_2 = 1; +#endif + + set_time(0); // initialize RTC + + /* Enable Ultra low power mode */ +// HAL_PWREx_EnableUltraLowPower(); + + /* Enable the fast wake up from Ultra low power mode */ +// HAL_PWREx_EnableFastWakeUp(); + +// __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF); + +// NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)rtc_wkup_irq); +// NVIC_EnableIRQ(RTC_WKUP_IRQn); + +// hdr_fem_csd = 0; + + hal_enableIRQs(); + +// GPIOA->MODER |= 0x01415500; // unused pins as outputs: PA4, PA5, PA6, PA7, PA8, (PA11,PA12 USB) +// GPIOB->MODER |= 0x00000401; // unused pins as outputs: PB0(HDR_DIO1), PB5 (PB10 pulled hi by LED), PB3-T_SWO +// GPIOC->MODER |= 0x00000041; // unused pins as outputs: PC0(HDR_FEM_CSD), PC3(SPI3_enable) + + debugSW("hal_init exit\r\n"); + +} + +time_t lastSeconds = 0xFFFFF; +u4_t hal_ticks () +{ + time_t seconds = time(NULL); + if(seconds != lastSeconds) + { + lastSeconds = seconds; + debugSW("hal_ticks enter %d\r\n",seconds << 14); + } +// RTC_DateTypeDef dateStruct; +// RTC_TimeTypeDef timeStruct; +// struct tm timeinfo; +// uint16_t sub_seconds; + +// RtcHandle.Instance = RTC; + + // Read actual date and time + // Warning: the time must be read first! +// HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN); +// HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN); +// sub_seconds = 16384 - timeStruct.SubSeconds; // RTC_SSR counts down + + // Setup a tm structure based on the RTC +// timeinfo.tm_wday = dateStruct.WeekDay; +// timeinfo.tm_mon = dateStruct.Month - 1; +// timeinfo.tm_mday = dateStruct.Date; +// timeinfo.tm_year = dateStruct.Year + 100; +// timeinfo.tm_hour = timeStruct.Hours; +// timeinfo.tm_min = timeStruct.Minutes; +// timeinfo.tm_sec = timeStruct.Seconds; + + // Convert to timestamp +// time_t t = mktime(&timeinfo); + + // 14: SSR is driven at 16384Hz +// t <<= 14; +// return t | sub_seconds; + return seconds << 14; +} + +void hal_waitUntil (u4_t time) +{ + debugSW("hal_waitUntil %d\r\n", time); + while (hal_ticks() < time) + asm("nop"); + debugSW("hal_waitUntil exit\r\n"); +} + + +volatile char deep_sleep; +/* return 1 if target time is soon, return 0 if timer was programmed */ +u1_t hal_checkTimer (u4_t time) +{ + int d = time - hal_ticks(); + if(d == 0) + return 1; + sleepTimeout = time; + debugSW("hal_checkTimer %d %d %d\r\n",time,d,sleepTimeout); + +// HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle); +// __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF); + +// if (d < 0x10000) { // less than 4s +// deep_sleep = 0; +// if (d < 4) +// return 1; // very soon +// if (d > ms2osticks(100)) { +// d -= 13; // HSE_PLL startup time +// deep_sleep = 1; +// } + // 61.035us steps +// HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d, RTC_WAKEUPCLOCK_RTCCLK_DIV2); +// } else if (d < 0x20000) { // less than 8s +// d -= 6; // HSE_PLL startup time +// deep_sleep = 1; + // 122us steps +// HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 1, RTC_WAKEUPCLOCK_RTCCLK_DIV4); +// } else if (d < 0x40000) { // less than 16s +// deep_sleep = 1; + // 244us steps +// HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 2, RTC_WAKEUPCLOCK_RTCCLK_DIV8); +// } else if (d < 0x80000) { // less than 32s +// deep_sleep = 1; + // 488us steps +// HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 3, RTC_WAKEUPCLOCK_RTCCLK_DIV16); +// } else { +// deep_sleep = 1; + // 1s steps to 18hours +// HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 14, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); + /* RTC_WAKEUPCLOCK_CK_SPRE_17BITS: 18h to 36h */ + /*for (;;) + asm("nop");*/ +// } + debugSW("hal_checkTimer exit\r\n"); + + return 0; +} + +#define SLEEP_DEBUG 1 + +void hal_sleep () +{ + debugSW("hal_sleep enter\r\n"); + hal_waitUntil(sleepTimeout); +// #ifdef SLEEP_DEBUG +// u4_t start_tick, end_tick; +// volatile uint32_t time_asleep; +//#endif /* SLEEP_DEBUG */ + +//#ifdef USE_DEBUGGER +// HAL_EnableDBGStopMode(); +// if (!DBGMCU->CR & DBGMCU_CR_DBG_STOP) +// for (;;) asm("nop"); +//#endif /* USE_DEBUGGER */ + + //printf("%x cr:%06x isr:%04x %d\r\n", RtcHandle.Instance->WUTR, RtcHandle.Instance->CR, RtcHandle.Instance->ISR, deep_sleep); + //debug_done(); + +// if (deep_sleep) +// debug_done(); // wait here if debug still printing + +// if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&RtcHandle, RTC_FLAG_WUTF) == 0) { + // set gpio for sleep +//#ifdef SLEEP_DEBUG +// start_tick = hal_ticks(); +//#endif /* SLEEP_DEBUG */ + + +// if (deep_sleep) { +//#ifndef USE_DEBUGGER + /* PA13 to undriven JTMS/SWDIO pin (from AF0 to GPIO), and PA2 */ +// GPIOA->MODER &= 0xf7ffffdf; +// GPIOB->MODER &= 0xffffdfff; // PB6 UART_TX to input +//#endif +// deepsleep(); // blocks until waking +//#ifndef USE_DEBUGGER +// /* PA13 back to JTMS/SWDIO pin (from GPIO to AF0), and PA2 */ +// GPIOA->MODER |= 0x08000020; +// GPIOB->MODER |= 0x00002000; // PB6 input to UART_TX +//#endif +// } else +// sleep(); // blocks until waking + +//#ifdef SLEEP_DEBUG +// end_tick = hal_ticks(); +// time_asleep = end_tick - start_tick; +// printf("%u = %u - %u\r\n", time_asleep, end_tick, start_tick); +//#endif /* SLEEP_DEBUG */ + // restore gpio from sleep +// } + debugSW("hal_sleep exit\r\n"); +} + +void hal_pin_nss (u1_t val) +{ + nss = val; +} + +u1_t hal_spi (u1_t out) +{ +// return spi.write(out); + u1_t res = spi.write(out); + debugSW("hal_spi %02X %02X\r\n",out, res); + return(res); +} + +// 0=RX 1=TX +/*void hal_pin_rxtx (u1_t val) +{ + rxtx = !val; +}*/ +#define OPMODE_LORA 0x80 +#define OPMODE_MASK 0x07 +#define OPMODE_SLEEP 0x00 +#define OPMODE_STANDBY 0x01 +#define OPMODE_FSTX 0x02 +#define OPMODE_TX 0x03 +#define OPMODE_FSRX 0x04 +#define OPMODE_RX 0x05 +#define OPMODE_RX_SINGLE 0x06 +#define OPMODE_CAD 0x07 +void hal_opmode(u1_t mode, u1_t pa_boost) +{ + debugSW("hal_opmode %02X %02X\r\n",mode, pa_boost); +// if (mode == OPMODE_TX) { // start of transmission +// if (pa_boost) { +// rfsw2 = 0; +// rfsw1 = 1; +// } else { +// rfsw2 = 1; +// rfsw1 = 0; +// } +// hdr_fem_csd = 0; // debug +// } else if (mode == OPMODE_RX || mode == OPMODE_RX_SINGLE || mode == OPMODE_CAD) { // start of reception +// rfsw2 = 1; +// rfsw1 = 1; +// hdr_fem_csd = 1; // debug +// } else { // RF switch shutdown +// rfsw2 = 0; +// rfsw1 = 0; +// hdr_fem_csd = 0; // debug +// } + debugSW("hal_opmode exit\r\n"); +} + +void hal_pin_rst (u1_t val) +{ + debugSW("hal_pin_rst %02X\r\n",val); +// if (val == 0 || val == 1) { // drive pin +// rst.output(); +// rst = val; +// } else { // keep pin floating +// rst.input(); +// } + debugSW("hal_pin_rst exit\r\n"); +}