Skip to content

Commit

Permalink
LMIC stack
Browse files Browse the repository at this point in the history
* Readded commit 93b5466
* os_runnloop has able to enter in sleep mode if there are nothing to do. os_runnloop are resumed when an interrupt is triggered on one of the DIO lines
* Added mutex in hal_lmic for protect some regions
* Put msgid in RTC mem in lora_lmic. This will used when implementing ABP
* Map some functions to the IRAM to prevent problems when accessing spi flash at interrupt handlers
* Removed compilation warnings in luaB_try used in LoRa WAN tests
* Removed unused files
  • Loading branch information
jolivepetrus committed Nov 25, 2016
1 parent 3689351 commit 3d90e36
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 54 deletions.
5 changes: 0 additions & 5 deletions components/lua_rtos/Lua/adds/luaconf.h
Expand Up @@ -245,11 +245,6 @@
#define LOSLIB_OPEN_ADDS
#endif

#ifdef LUA_LIB
#undef LUA_LIB
#include <Lua/modules/lbaselib_adds.inc>
#endif

#ifdef liolib_c
#undef liolib_c
#include <Lua/modules/liolib_adds.inc>
Expand Down
2 changes: 2 additions & 0 deletions components/lua_rtos/Lua/src/lbaselib.c
Expand Up @@ -20,6 +20,8 @@

LUALIB_API void luaL_checkanytable (lua_State *L, int arg);

#include <Lua/modules/lbaselib_adds.inc>

static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
Expand Down
4 changes: 2 additions & 2 deletions components/lua_rtos/Makefile.projbuild
Expand Up @@ -51,7 +51,7 @@ CFLAGS += -DOSTICKS_PER_SEC=50000
CFLAGS += -DLMIC_JOIN_FAILED_AFTER_868_864=1 # JOIN_FAILED after test 868 / 864, don't try lower DR

CFLAGS += -DLMIC_SPI_KHZ=10000
CFLAGS += -DLMIC_DEBUG_LEVEL=1
CFLAGS += -DLMIC_DEBUG_LEVEL=0

#
# SDCARD configuration
Expand Down Expand Up @@ -84,7 +84,7 @@ CFLAGS += -DI2C5_PINS=0
#
# Lua configuration
#
CFLAGS += -DDEBUG_FREE_MEM=1 # Enable LUA free mem debug utility (only for debug purposes)
CFLAGS += -DDEBUG_FREE_MEM=0 # Enable LUA free mem debug utility (only for debug purposes)
CFLAGS += -DLUA_USE_LUA_LOCK=0 # Enable if Lua must use real lua_lock / lua_unlock implementation
CFLAGS += -DLUA_USE_SAFE_SIGNAL=0 # Enable use of LuaOS safe signal (experimental)
# CFLAGS += -DSTRCACHE_N=1
Expand Down
129 changes: 114 additions & 15 deletions components/lua_rtos/drivers/lmic_hal.c
Expand Up @@ -38,26 +38,49 @@
#include "freertos/timers.h"
#include "freertos/event_groups.h"

#include "esp_attr.h"
#include "soc/gpio_reg.h"

#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/delay.h>
#include <sys/syslog.h>
#include <sys/mutex.h>

#include <drivers/gpio.h>
#include <drivers/spi.h>

#include "esp_attr.h"
#include "soc/gpio_reg.h"
extern unsigned port_interruptNesting[portNUM_PROCESSORS];

/*
* This is an adapter function for call radio_irq_handler from a callback
* Mutex for protect critical regions
*/
static osjob_t dio_job;
static struct mtx lmic_hal_mtx;

static void deferred_dio_intr_handler(osjob_t *j) {
radio_irq_handler(0);
}
/*
* This variables are for doing things only one time.
*
* nested is for enable / disable interrupts once.
* sleeped is for sleep os_runloop once.
* resumed is for resume os_runloop once.
*
* For example, enable / disable interrupts are done as follows:
*
* enable - disable - enable - disable
*
*/
static int nested = 0;
static int sleeped = 0;
static int resumed = 0;

/*
* This is an event group handler for sleep / resume os_runloop.
* When os_runloop has nothing to do waits for an event.
*/
#define evLMIC_SLEEP ( 1 << 0 )

EventGroupHandle_t lmicSleepEvent;

/*
* This is the LMIC interrupt handler. This interrupt is attached to the transceiver
Expand All @@ -71,10 +94,15 @@ static void IRAM_ATTR dio_intr_handler(void *args) {
u4_t status_l = READ_PERI_REG(GPIO_STATUS_REG) & GPIO_STATUS_INT;
u4_t status_h = READ_PERI_REG(GPIO_STATUS1_REG) & GPIO_STATUS1_INT;

/*
* Don't change the position of this code. Interrupt status must be clean
* in this point.
*/
WRITE_PERI_REG(GPIO_STATUS_W1TC_REG, status_l);
WRITE_PERI_REG(GPIO_STATUS1_W1TC_REG, status_h);

os_setCallback(&dio_job, deferred_dio_intr_handler);
radio_irq_handler(0);
hal_resume();
}

void hal_init (void) {
Expand Down Expand Up @@ -115,12 +143,18 @@ void hal_init (void) {
gpio_set_intr_type(LMIC_DIO2, GPIO_INTR_POSEDGE);
gpio_intr_enable(LMIC_DIO2);
}

// Create lmicSleepEvent
lmicSleepEvent = xEventGroupCreate();

// Create mutex
mtx_init(&lmic_hal_mtx, NULL, NULL, 0);
}

/*
* drive radio NSS pin (0=low, 1=high).
*/
void hal_pin_nss (u1_t val) {
void IRAM_ATTR hal_pin_nss (u1_t val) {
spi_set_cspin(LMIC_SPI, LMIC_CS);

if (!val) {
Expand Down Expand Up @@ -157,20 +191,85 @@ void hal_pin_rst (u1_t val) {
* - write given byte 'outval'
* - read byte and return value
*/
u1_t hal_spi (u1_t outval) {
u1_t IRAM_ATTR hal_spi (u1_t outval) {
return spi_transfer(LMIC_SPI, outval);
}

void hal_disableIRQs (void) {
void IRAM_ATTR hal_disableIRQs (void) {
int disable = 0;

mtx_lock(&lmic_hal_mtx);

if (nested++ == 0) {
disable = 1;
}

mtx_unlock(&lmic_hal_mtx);

if (disable) {
portDISABLE_INTERRUPTS();
}
}

void hal_enableIRQs (void) {
void IRAM_ATTR hal_enableIRQs (void) {
int enable = 0;

mtx_lock(&lmic_hal_mtx);

if (--nested == 0) {
enable = 1;
}

mtx_unlock(&lmic_hal_mtx);

if (enable) {
portENABLE_INTERRUPTS();
}
}

void IRAM_ATTR hal_resume (void) {
int resume = 0;

mtx_lock(&lmic_hal_mtx);

if (resumed == 0) {
sleeped = 0;
resumed = 1;
resume = 1;
}

mtx_unlock(&lmic_hal_mtx);

if (resume) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

if (port_interruptNesting[xPortGetCoreID()] != 0) {
xEventGroupSetBitsFromISR(lmicSleepEvent, evLMIC_SLEEP, &xHigherPriorityTaskWoken);
} else {
xEventGroupSetBits(lmicSleepEvent, evLMIC_SLEEP);
}
}
}

void hal_sleep (void) {
int sleep = 0;

mtx_lock(&lmic_hal_mtx);

if (sleeped == 0) {
sleeped = 1;
resumed = 0;
sleep = 1;
}

mtx_unlock(&lmic_hal_mtx);

if (sleep) {
xEventGroupWaitBits(lmicSleepEvent, evLMIC_SLEEP, pdTRUE, pdFALSE, portMAX_DELAY);
}
}

u4_t hal_ticks () {
u4_t IRAM_ATTR hal_ticks () {
struct timeval tv;

gettimeofday(&tv, NULL);
Expand Down Expand Up @@ -208,8 +307,8 @@ u1_t hal_checkTimer (u4_t targettime) {
* - action could be HALT or reboot
*/
void hal_failed (char *file, int line) {
printf("assert: at %s, line %d\n", file, line);
syslog(LOG_ERR, "%lu: assert at $s, line %s\n", os_getTime(), file, line);

for(;;);
}

Expand Down
7 changes: 6 additions & 1 deletion components/lua_rtos/drivers/lora_lmic.c
Expand Up @@ -37,6 +37,8 @@
#include "freertos/timers.h"
#include "freertos/event_groups.h"

#include "esp_attr.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
Expand Down Expand Up @@ -74,7 +76,7 @@ static u1_t DEVEUI[8] = {0,0,0,0,0,0,0,0};
static u1_t APPKEY[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

// Current message id
static u4_t msgid = 0;
RTC_DATA_ATTR static u4_t msgid = 0;

// If = 1 driver is setup, if = 0 is not setup
static int setup = 0;
Expand Down Expand Up @@ -531,6 +533,9 @@ int lora_join() {
return LORA_OK;
}

// If we use join, set msgid to 0
msgid = 0;

// Set DR
if (!adr) {
LMIC_setDrTxpow(current_dr, 14);
Expand Down
6 changes: 4 additions & 2 deletions components/lua_rtos/drivers/spi.c
Expand Up @@ -39,6 +39,8 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_attr.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
Expand Down Expand Up @@ -335,7 +337,7 @@ void spi_pins(int unit, unsigned char *sdi, unsigned char *sdo, unsigned char *s
spi_set_cspin(unit, *cs);
}

static void spi_master_op(int unit, unsigned int word_size, unsigned int len, unsigned char *out, unsigned char *in) {
static void IRAM_ATTR spi_master_op(int unit, unsigned int word_size, unsigned int len, unsigned char *out, unsigned char *in) {
unsigned int bytes = word_size * len; // Number of bytes to write / read
unsigned int idx = 0;

Expand Down Expand Up @@ -421,7 +423,7 @@ static void spi_master_op(int unit, unsigned int word_size, unsigned int len, un
* This is blocking, and waits for the transfer to complete
* before returning. Times out after a certain period.
*/
unsigned int spi_transfer(int unit, unsigned int data) {
unsigned int IRAM_ATTR spi_transfer(int unit, unsigned int data) {
unsigned char read;

spi_master_op(unit, 1, 1, (unsigned char *)(&data), &read);
Expand Down
14 changes: 0 additions & 14 deletions components/lua_rtos/lmic/config.h

This file was deleted.

5 changes: 5 additions & 0 deletions components/lua_rtos/lmic/hal.h
Expand Up @@ -60,6 +60,11 @@ void hal_disableIRQs (void);
*/
void hal_enableIRQs (void);

/*
* resume sysrem and CPU
*/
void hal_resume(void);

/*
* put system and CPU in low-power mode, sleep until interrupt.
*/
Expand Down
12 changes: 9 additions & 3 deletions components/lua_rtos/lmic/oslmic.c
Expand Up @@ -20,6 +20,8 @@
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_attr.h"

// LMIC run loop, as a FreeRTOS task
void os_runloop(void *pvParameters);

Expand Down Expand Up @@ -52,20 +54,20 @@ static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
return 0;
}

ostime_t os_getTime () {
ostime_t IRAM_ATTR os_getTime () {
return hal_ticks();
}

// clear scheduled job
void os_clearCallback (osjob_t* job) {
void IRAM_ATTR os_clearCallback (osjob_t* job) {
hal_disableIRQs();
unlinkjob(&OS.scheduledjobs, job);
unlinkjob(&OS.runnablejobs, job);
hal_enableIRQs();
}

// schedule immediately runnable job
void os_setCallback (osjob_t* job, osjobcb_t cb) {
void IRAM_ATTR os_setCallback (osjob_t* job, osjobcb_t cb) {
osjob_t** pnext;
hal_disableIRQs();
// remove if job was already queued
Expand Down Expand Up @@ -122,6 +124,10 @@ void os_runloop(void *pvParameters) {

if (j) { // run job callback
j->func(j);
} else {
if (!OS.runnablejobs && !OS.scheduledjobs) {
hal_sleep();
}
}
}
}
Expand Down

0 comments on commit 3d90e36

Please sign in to comment.