hello world

Fork of lmic_MOTE_L152RC by Semtech

Files at this revision

API Documentation at this revision

Comitter:
tmulrooney
Date:
Tue Feb 09 00:28:59 2016 +0000
Parent:
8:0faa1bb768b5
Commit message:
hello world

Changed in this revision

TARGET_MOTE_L152RC/debug.cpp Show diff for this revision Revisions of this file
TARGET_MOTE_L152RC/hal.cpp Show diff for this revision Revisions of this file
TARGET_MOTE_L152RC/hal.h Show diff for this revision Revisions of this file
debug.cpp Show annotated file Show diff for this revision Revisions of this file
debug.h Show annotated file Show diff for this revision Revisions of this file
hal.cpp Show annotated file Show diff for this revision Revisions of this file
hal.h Show annotated file Show diff for this revision Revisions of this file
radio.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 0faa1bb768b5 -r 671d85a0f15b TARGET_MOTE_L152RC/debug.cpp
--- a/TARGET_MOTE_L152RC/debug.cpp	Wed Oct 21 01:03:34 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-//#include "oslmic.h"
-#include "lmic.h"
-#include "debug.h"
-#include "mbed.h"
-
-Serial pc(USBTX, USBRX);
-
-static DigitalOut red_led(PB_1);
-#define LED_ON  0
-#define LED_OFF 1
-
-void debug_init()
-{
-    pc.baud(115200);
-
-    // print banner
-    debug_str("\r\n============== DEBUG STARTED ==============\r\n");
-
-    red_led = LED_OFF;
-}
-
-void debug_str (const char* str)
-{
-    debug("%s", str);
-}
-
-void debug_event (int ev)
-{
-    static const u1_t* evnames[] = {
-        [EV_SCAN_TIMEOUT]   = "SCAN_TIMEOUT",
-        [EV_BEACON_FOUND]   = "BEACON_FOUND",
-        [EV_BEACON_MISSED]  = "BEACON_MISSED",
-        [EV_BEACON_TRACKED] = "BEACON_TRACKED",
-        [EV_JOINING]        = "JOINING",
-        [EV_JOINED]         = "JOINED",
-        [EV_RFU1]           = "RFU1",
-        [EV_JOIN_FAILED]    = "JOIN_FAILED",
-        [EV_REJOIN_FAILED]  = "REJOIN_FAILED",
-        [EV_TXCOMPLETE]     = "TXCOMPLETE",
-        [EV_LOST_TSYNC]     = "LOST_TSYNC",
-        [EV_RESET]          = "RESET",
-        [EV_RXCOMPLETE]     = "RXCOMPLETE",
-        [EV_LINK_DEAD]      = "LINK_DEAD",
-        [EV_LINK_ALIVE]     = "LINK_ALIVE",
-    };
-
-    debug("%s\r\n", evnames[ev]);
-}
-
-void debug_val (const char* label, u4_t val)
-{
-    debug("%s%d\r\n", label, val);
-}
-
-void debug_buf(const u1_t* buf, u2_t len)
-{
-    while (len--) {
-        debug("%02x ", *buf++);
-    }
-    debug("\r\n");
-}
-
-void debug_led(unsigned char on)
-{
-    if (on)
-        red_led = LED_ON;
-    else
-        red_led = LED_OFF;
-}
-
-void debug_done()
-{
-    /* block until last bit sent out debug UART */
-    while (!(USART2->SR & UART_FLAG_TC))
-        __NOP();
-}
diff -r 0faa1bb768b5 -r 671d85a0f15b TARGET_MOTE_L152RC/hal.cpp
--- a/TARGET_MOTE_L152RC/hal.cpp	Wed Oct 21 01:03:34 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +0,0 @@
-/* HAL for MOTE_L152RC */
-
-#include "mbed.h"
-#include "oslmic.h"
-#include "debug.h"
-
-#define RADIO_MOSI      PB_15
-#define RADIO_MISO      PB_14
-#define RADIO_SCLK      PB_13
-#define RADIO_NSS       PB_12
-#define RESET_PIN       PC_2
-
-#define RFSW1                    PC_4 //NorAm_Mote RFSwitch_CNTR_1
-#define RFSW2                    PC_13 //NorAm_Mote RFSwitch_CNTR_2
-
-static DigitalOut nss(RADIO_NSS);
-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(PC_0);
-
-static InterruptIn dio0(PC_6);
-static InterruptIn dio1(PC_10);
-static InterruptIn dio2(PC_11); 
-
-extern RTC_HandleTypeDef RtcHandle;
-
-// 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)
-{
-    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.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)     
-    
-
-}
-
-u4_t hal_ticks ()
-{
-    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;
-}
-
-void hal_waitUntil (u4_t time)
-{
-    while (hal_ticks() < time)
-        asm("nop");
-}
-
-
-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();
-
-    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");*/
-    }
-    
-    return 0;
-}
-
-//#define SLEEP_DEBUG 1
-
-void hal_sleep ()
-{
-#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
-    }
-}
-
-void hal_pin_nss (u1_t val)
-{
-    nss = val;
-}
-
-u1_t hal_spi (u1_t out)
-{
-    return spi.write(out);
-}
-
-// 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)
-{
-    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   
-    }
-}
-
-void hal_pin_rst (u1_t val)
-{
-    if (val == 0 || val == 1) { // drive pin
-        rst.output();
-        rst = val;
-    } else { // keep pin floating
-        rst.input();
-    }
-}
-
diff -r 0faa1bb768b5 -r 671d85a0f15b TARGET_MOTE_L152RC/hal.h
--- a/TARGET_MOTE_L152RC/hal.h	Wed Oct 21 01:03:34 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014-2015 IBM Corporation.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    IBM Zurich Research Lab - initial API, implementation and documentation
- *******************************************************************************/
-
-#ifndef _hal_hpp_
-#define _hal_hpp_
-
-/*
- * initialize hardware (IO, SPI, TIMER, IRQ).
- */
-void hal_init (void);
-
-/*
- * drive radio NSS pin (0=low, 1=high).
- */
-void hal_pin_nss (u1_t val);
-
-/*
- * drive radio RX/TX pins (0=rx, 1=tx).
- */
-//void hal_pin_rxtx (u1_t val);
-void hal_opmode(u1_t mode, u1_t pa_boost);
-
-/*
- * control radio RST pin (0=low, 1=high, 2=floating)
- */
-void hal_pin_rst (u1_t val);
-
-/*
- * perform 8-bit SPI transaction with radio.
- *   - write given byte 'outval'
- *   - read byte and return value
- */
-u1_t hal_spi (u1_t outval);
-
-/*
- * disable all CPU interrupts.
- *   - might be invoked nested 
- *   - will be followed by matching call to hal_enableIRQs()
- */
-void hal_disableIRQs (void);
-
-/*
- * enable CPU interrupts.
- */
-void hal_enableIRQs (void);
-
-/*
- * put system and CPU in low-power mode, sleep until interrupt.
- */
-void hal_sleep (void);
-
-/*
- * return 32-bit system time in ticks.
- */
-u4_t hal_ticks (void);
-
-/*
- * busy-wait until specified timestamp (in ticks) is reached.
- */
-void hal_waitUntil (u4_t time);
-
-/*
- * check and rewind timer for target time.
- *   - return 1 if target time is close
- *   - otherwise rewind timer for target time or full period and return 0
- */
-u1_t hal_checkTimer (u4_t targettime);
-
-/*
- * perform fatal failure action.
- *   - called by assertions
- *   - action could be HALT or reboot
- */
-void hal_failed (void);
-
-#ifndef OSTICKS_PER_SEC
-#define OSTICKS_PER_SEC 16384
-#elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516
-#error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long.
-#endif
-
-#endif // _hal_hpp_
diff -r 0faa1bb768b5 -r 671d85a0f15b debug.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debug.cpp	Tue Feb 09 00:28:59 2016 +0000
@@ -0,0 +1,76 @@
+//#include "oslmic.h"
+#include "lmic.h"
+#include "debug.h"
+#include "mbed.h"
+
+Serial pc(PTE0, PTE1);
+
+static DigitalOut red_led(PTA1);
+#define LED_ON  0
+#define LED_OFF 1
+
+void debug_init()
+{
+    pc.baud(115200);
+
+    // print banner
+    debug_str("\r\n============== DEBUG STARTED ==============\r\n");
+
+    red_led = LED_OFF;
+}
+
+void debug_str (const char* str)
+{
+    debug("%s", str);
+}
+
+void debug_event (int ev)
+{
+    static const u1_t* evnames[] = {
+        [EV_SCAN_TIMEOUT]   = "SCAN_TIMEOUT",
+        [EV_BEACON_FOUND]   = "BEACON_FOUND",
+        [EV_BEACON_MISSED]  = "BEACON_MISSED",
+        [EV_BEACON_TRACKED] = "BEACON_TRACKED",
+        [EV_JOINING]        = "JOINING",
+        [EV_JOINED]         = "JOINED",
+        [EV_RFU1]           = "RFU1",
+        [EV_JOIN_FAILED]    = "JOIN_FAILED",
+        [EV_REJOIN_FAILED]  = "REJOIN_FAILED",
+        [EV_TXCOMPLETE]     = "TXCOMPLETE",
+        [EV_LOST_TSYNC]     = "LOST_TSYNC",
+        [EV_RESET]          = "RESET",
+        [EV_RXCOMPLETE]     = "RXCOMPLETE",
+        [EV_LINK_DEAD]      = "LINK_DEAD",
+        [EV_LINK_ALIVE]     = "LINK_ALIVE",
+    };
+
+    debug("%s\r\n", evnames[ev]);
+}
+
+void debug_val (const char* label, u4_t val)
+{
+    debug("%s%d\r\n", label, val);
+}
+
+void debug_buf(const u1_t* buf, u2_t len)
+{
+    while (len--) {
+        debug("%02x ", *buf++);
+    }
+    debug("\r\n");
+}
+
+void debug_led(unsigned char on)
+{
+    if (on)
+        red_led = LED_ON;
+    else
+        red_led = LED_OFF;
+}
+
+void debug_done()
+{
+    /* block until last bit sent out debug UART */
+//    while (!(USART2->SR & UART_FLAG_TC))
+//        __NOP();
+}
diff -r 0faa1bb768b5 -r 671d85a0f15b debug.h
--- a/debug.h	Wed Oct 21 01:03:34 2015 +0000
+++ b/debug.h	Tue Feb 09 00:28:59 2016 +0000
@@ -23,6 +23,24 @@
     va_end(args);
 }
 
+#define NDEBUG
+#ifndef NDEBUG
+
+/** Output a debug message
+ * 
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debugSW(const char *format, ...) {
+    va_list args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+}
+
+#else
+static inline void debugSW(const char *format, ...) {}
+#endif
+
 // intialize debug library
 void debug_init (void);
 
diff -r 0faa1bb768b5 -r 671d85a0f15b hal.cpp
--- /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");
+}
diff -r 0faa1bb768b5 -r 671d85a0f15b hal.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hal.h	Tue Feb 09 00:28:59 2016 +0000
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2015 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Zurich Research Lab - initial API, implementation and documentation
+ *******************************************************************************/
+
+#ifndef _hal_hpp_
+#define _hal_hpp_
+
+/*
+ * initialize hardware (IO, SPI, TIMER, IRQ).
+ */
+void hal_init (void);
+
+/*
+ * drive radio NSS pin (0=low, 1=high).
+ */
+void hal_pin_nss (u1_t val);
+
+/*
+ * drive radio RX/TX pins (0=rx, 1=tx).
+ */
+//void hal_pin_rxtx (u1_t val);
+void hal_opmode(u1_t mode, u1_t pa_boost);
+
+/*
+ * control radio RST pin (0=low, 1=high, 2=floating)
+ */
+void hal_pin_rst (u1_t val);
+
+/*
+ * perform 8-bit SPI transaction with radio.
+ *   - write given byte 'outval'
+ *   - read byte and return value
+ */
+u1_t hal_spi (u1_t outval);
+
+/*
+ * disable all CPU interrupts.
+ *   - might be invoked nested 
+ *   - will be followed by matching call to hal_enableIRQs()
+ */
+void hal_disableIRQs (void);
+
+/*
+ * enable CPU interrupts.
+ */
+void hal_enableIRQs (void);
+
+/*
+ * put system and CPU in low-power mode, sleep until interrupt.
+ */
+void hal_sleep (void);
+
+/*
+ * return 32-bit system time in ticks.
+ */
+u4_t hal_ticks (void);
+
+/*
+ * busy-wait until specified timestamp (in ticks) is reached.
+ */
+void hal_waitUntil (u4_t time);
+
+/*
+ * check and rewind timer for target time.
+ *   - return 1 if target time is close
+ *   - otherwise rewind timer for target time or full period and return 0
+ */
+u1_t hal_checkTimer (u4_t targettime);
+
+/*
+ * perform fatal failure action.
+ *   - called by assertions
+ *   - action could be HALT or reboot
+ */
+void hal_failed (void);
+
+#ifndef OSTICKS_PER_SEC
+#define OSTICKS_PER_SEC 16384
+#elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516
+#error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long.
+#endif
+
+#endif // _hal_hpp_
diff -r 0faa1bb768b5 -r 671d85a0f15b radio.cpp
--- a/radio.cpp	Wed Oct 21 01:03:34 2015 +0000
+++ b/radio.cpp	Tue Feb 09 00:28:59 2016 +0000
@@ -397,7 +397,7 @@
     writeReg(RegFrfLsb, (u1_t)(frf>> 0));
 }
 
-DigitalOut pd2(PD_2);   // power amplifier voltage control pin
+//DigitalOut pd2(PTC1);   // power amplifier voltage control pin *** TODO ***
 
 /*     pd2=0   pd2=1
 op pab  rfo     rfo
@@ -444,7 +444,7 @@
     if (LMIC.txpow > 19) {
         PaSelect = 0x00;    // use RFO
         writeReg(RegPaConfig, PaSelect | rfo_table[LMIC.txpow-20]);
-        pd2 = 0;
+//        pd2 = 0;
     } else {
         PaSelect = 0x80;    // use PA_BOOST 
         writeReg(RegPaConfig, PaSelect | boost_table[LMIC.txpow]);