first draft

Dependencies:   LMiC SX1272Libx mbed

Fork of LoRaWAN-lmic-app by Semtech

hal.cpp

Committer:
tmulrooney
Date:
2016-02-26
Revision:
10:497ef83ca19f
Parent:
6:fc465060b63e

File content as of revision 10:497ef83ca19f:

/*******************************************************************************
 * Copyright (c) 2014 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
 *    Semtech Apps Team       - Modified to support the MBED sx1276 driver
 *                              library.
 *                              Possibility to use original or Semtech's MBED
 *                              radio driver. The selection is done by setting
 *                              USE_SMTC_RADIO_DRIVER preprocessing directive
 *                              in lmic.h
 *******************************************************************************/
#include "mbed.h"
#include "lmic.h"
#include "debug.h"

#if !USE_SMTC_RADIO_DRIVER

extern void radio_irq_handler( u1_t dio );

static DigitalOut nss( PTD4 );
static SPI spi( PTD6, PTD7, PTD5 ); // ( mosi, miso, sclk )
 
static DigitalInOut rst( A0 );
static DigitalOut rxtx( PTC6 );
 
static InterruptIn dio0( PTC2 );
static InterruptIn dio1( PTC4 );
static InterruptIn dio2( PTC3 ); 

static void dio0Irq( void ) {
    radio_irq_handler( 0 );
}

static void dio1Irq( void ) {
    radio_irq_handler( 1 );
}

static void dio2Irq( void ) {
    radio_irq_handler( 2 );
}

#endif

static u1_t irqlevel = 0;
static u4_t ticks = 0;

static Timer timer;
static Ticker ticker;

static void reset_timer( void ) 
{
    debug("reset_timer enter\r\n");
    ticks += timer.read_us( ) >> 6;
    timer.reset( );
}

void hal_init( void ) 
{
   debug("hal_init enter\r\n");
     __disable_irq( );
     irqlevel = 0;

#if !USE_SMTC_RADIO_DRIVER
    // 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;
#endif
    // configure timer
    timer.start( );
    ticker.attach_us( reset_timer, 10000000 ); // reset timer every 10sec
     __enable_irq( );
   debug("hal_init exit\r\n");
}

#if !USE_SMTC_RADIO_DRIVER

void hal_pin_rxtx( u1_t val ) 
{
  debug("hal_pin_rxtx enter %d\r\n",val);
    rxtx = !val;
}

void hal_pin_nss( u1_t val ) 
{
 debug("hal_pin_nss enter %d\r\n",val);
    nss = val;
}

void hal_pin_rst( u1_t val ) 
{
debug("hal_pin_rst enter %d\r\n",val);
    if( val == 0 || val == 1 )
    { // drive pin
        rst.output( );
        rst = val;
    } 
    else
    { // keep pin floating
        rst.input( );
    }
}

u1_t hal_spi( u1_t out ) 
{
 debug("hal_spi enter\r\n");
   return spi.write( out );
}

#endif

void hal_disableIRQs( void ) 
{
 //debug("hal_disableIRQs enter\r\n");
   __disable_irq( );
    irqlevel++;
}

void hal_enableIRQs( void ) 
{
//debug("hal_enableIRQs enter\r\n");
    if( --irqlevel == 0 )
    {
        __enable_irq( );
    }
}

void hal_sleep( void ) 
{
//debug("hal_sleep enter\r\n");
    // NOP
}

u4_t hal_ticks( void ) 
{
    hal_disableIRQs( );
    int t = ticks + ( timer.read_us( ) >> 6 );
    hal_enableIRQs( );
//debug("hal_ticks exit %d\r\n",t);
    return t;
}

static u2_t deltaticks( u4_t time ) 
{
//    debug("deltaticks enter\r\n");
    u4_t t = hal_ticks( );
    s4_t d = time - t;
    if( d <= 0 ) {
        return 0;    // in the past
    }
    if( ( d >> 16 ) != 0 ) {
        return 0xFFFF; // far ahead
    }
    return ( u2_t )d;
}

void hal_waitUntil( u4_t time ) 
{
    debug("hal_waitUntil enter\r\n");
    while( deltaticks( time ) != 0 ); // busy wait until timestamp is reached
}

u1_t hal_checkTimer( u4_t time ) 
{
//    debug("hal_checkTimer enter\r\n");
    return ( deltaticks( time ) < 2 );
}

void hal_failed( void ) 
{
   debug("hal_failed enter\r\n");
    while( 1 );
}