Updates as of 2-17-16 for debugging K22F LoRa platform.

Fork of lmic_MOTE_L152RC by Timothy Mulrooney

hal.cpp

Committer:
jlcolemanmbed
Date:
2016-02-18
Revision:
12:febc37010b64
Parent:
11:671d85a0f15b

File content as of revision 12:febc37010b64:

/* 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                    PTC6 //NorAm_Mote RFSwitch_CNTR_1 *** TODO ***
#define RFSW2                    PTC6 //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 = 1; //revised to match PE4259 switch controls
//            rfsw1 = 1;
        } else {
            rfsw2 = 1;  //revised to match PE4259 switch controls
//           rfsw1 = 0;          
        }
//        hdr_fem_csd = 0;    // debug   
    } else if (mode == OPMODE_RX || mode == OPMODE_RX_SINGLE || mode == OPMODE_CAD) { // start of reception
        rfsw2 = 0;  //revised to match PE4259 switch controls
//       rfsw1 = 1; 
//       hdr_fem_csd = 1;    // debug        
    } else { // RF switch shutdown
        rfsw2 = 1;  //revised to match PE4259 switch controls
//        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");
}