authorNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Jan 2019 07:39:16 +0000 (08:39 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Jan 2019 07:39:16 +0000 (08:39 +0100)
apps/rf_sub1G/soream/Makefile [new file with mode: 0644]
apps/rf_sub1G/soream/README [new file with mode: 0644]
apps/rf_sub1G/soream/common.h [new file with mode: 0644]
apps/rf_sub1G/soream/config.c [new file with mode: 0644]
apps/rf_sub1G/soream/config.h [new file with mode: 0644]
apps/rf_sub1G/soream/main.c [new file with mode: 0644]
apps/rf_sub1G/soream/rf.c [new file with mode: 0644]
apps/rf_sub1G/soream/rf.h [new file with mode: 0644]

diff --git a/apps/rf_sub1G/soream/Makefile b/apps/rf_sub1G/soream/Makefile
new file mode 100644 (file)
index 0000000..41ae555
--- /dev/null
@@ -0,0 +1,21 @@
+# Makefile for apps
+
+MODULE = $(shell basename $(shell cd .. && pwd && cd -))
+NAME = $(shell basename $(CURDIR))
+
+# Add this to your ~/.vimrc in order to get proper function of :make in vim :
+# let $COMPILE_FROM_IDE = 1
+ifeq ($(strip $(COMPILE_FROM_IDE)),)
+       PRINT_DIRECTORY = --no-print-directory
+else
+       PRINT_DIRECTORY =
+       LANG = C
+endif
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../../.. ${PRINT_DIRECTORY} NAME=$(NAME) MODULE=$(MODULE) apps/$(MODULE)/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../../.. ${PRINT_DIRECTORY} $@
+
diff --git a/apps/rf_sub1G/soream/README b/apps/rf_sub1G/soream/README
new file mode 100644 (file)
index 0000000..5fac04f
--- /dev/null
@@ -0,0 +1,32 @@
+Sub 1GHz USB module - Soream application
+
+Copyright 2018 Nathael Pajani <nathael.pajani@ed3l.fr>
+
+
+/* ****************************************************************************
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+
+About the RF-Sub1GHz module :
+
+This module uses the CC1101 transceiver to provide Sub 1GHz Rf connectivity.
+
+The module also integrates a TMP101 temparature sensor, the usual bi-color led
+used for status, a RTC quartz, a DC-DC step-up for button battery power source
+support, and an extension port with a set of gpio, including ADC (2), PWM (2),
+I2C and SWD debug port.
+
diff --git a/apps/rf_sub1G/soream/common.h b/apps/rf_sub1G/soream/common.h
new file mode 100644 (file)
index 0000000..9cee852
--- /dev/null
@@ -0,0 +1,52 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/common.h
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#include "core/system.h"
+#include "core/systick.h"
+#include "core/pio.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+
+
+
+#define DEBUG 0
+
+#if (DEBUG == 1)
+ #define debug_printf(...) \
+   uprintf(UART0, __VA_ARGS__ );
+#else
+ #define debug_printf(...) ;
+#endif
+
+
+/***************************************************************************** */
+/* Shared global vars */
+extern volatile uint8_t check_rx;
+extern volatile uint8_t cc_tx;
+extern volatile uint8_t stay_on;
+#define  STAY_ON_RESET  10
+
+extern uint8_t address;
+extern uint8_t peer_address;
+
+
diff --git a/apps/rf_sub1G/soream/config.c b/apps/rf_sub1G/soream/config.c
new file mode 100644 (file)
index 0000000..5a46a52
--- /dev/null
@@ -0,0 +1,158 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/config.c
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+#include "common.h"
+
+#include "drivers/gpio.h"
+#include "drivers/ssp.h"
+#include "drivers/timers.h"
+
+#include "config.h"
+
+
+/***************************************************************************** */
+/* Pins configuration
+ * passed to set_pins() for pins configuration.
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* SPI */
+       { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL },
+       { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL },
+       { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL },
+       /* Timer  */
+       { LPC_TIMER_32B1_M0_PIO_0_23, LPC_TIMER_PIN_CONFIG },
+       /* GPIO */
+       { LPC_GPIO_0_15, LPC_IO_DIGITAL }, /* CC1101 Chip select */
+       { LPC_GPIO_0_6, LPC_IO_DIGITAL },  /* RF - GDO_0 */
+       ARRAY_LAST_PIO,
+};
+
+
+/******************************************************************************/
+/* Watchdog */
+void tmp_callback(void)
+{
+       serial_send_quickbyte(UART0, 'w');
+}
+
+const struct wdt_config wdconf = {
+       .clk_sel = WDT_CLK_IRC,
+       .intr_mode_only = 0,
+       .callback = tmp_callback,
+       .locks = 0,
+       .nb_clk = 0x2000000,
+       .wdt_window = 0,
+       .wdt_warn = 0x3FF,
+};
+
+
+/***************************************************************************** */
+void WAKEUP_Handler(void)
+{
+       /* Reset : the easiest way to get everything back in order */
+       NVIC_SystemReset();
+}
+
+const struct wakeup_pin wakers[] = {
+       { 6, EDGE_RISING }, /* GPIO_0_6 */
+       ARRAY_LAST_WAKER,
+};
+
+void system_sleeping_shutdown(void)
+{
+       timer_stop(LPC_TIMER_32B1);
+       stop_watchdog();
+       timer_off(LPC_TIMER_32B1);
+       serial_flush(UART0);
+       systick_timer_off();
+       enter_deep_sleep(1, 0, 1, wakers);
+}
+
+/***************************************************************************** */
+void light_config(void)
+{   
+       /* Timer configuration */
+       struct lpc_timer_pwm_config timer_conf = {
+               .nb_channels = 1,
+               .period_chan = 3,
+               .outputs = { 0, },
+       };
+       timer_conf.period = get_main_clock() / 100; /* 100Hz */
+       timer_conf.match_values[0] = timer_conf.period / 5; /* 20% duty cycle */
+       timer_pwm_config(LPC_TIMER_32B1, &timer_conf);
+}
+
+void set_light_on(void)
+{
+       /* Start the timer */
+       timer_start(LPC_TIMER_32B1);
+}
+
+
+/***************************************************************************** */
+void read_user_data(void)
+{
+       /* TODO : read from user flash if multiple systems are to be used together */
+       address = 4;
+       peer_address = 4;
+}
+
+/***************************************************************************** */
+void system_init(void)
+{
+       /* Stop the watchdog */
+       startup_watchdog_disable(); /* Do it right now, before it gets a chance to break in */
+       /* Power and main clocks */
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       /* PIO and GPIO config */
+       set_pins(common_pins);
+       gpio_on();
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+       /* Internal communication blocks */
+       uart_on(UART0, 115200, NULL);
+       ssp_master_on(0, LPC_SSP_FRAME_SPI, 8, 4*1000*1000); /* bus_num, frame_type, data_width, rate */
+       timer_on(LPC_TIMER_32B1, 0, NULL);
+       /* Watchdog */
+       watchdog_config(&wdconf);
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       uprintf(UART0, name);
+       while (1);
+}
+
+
diff --git a/apps/rf_sub1G/soream/config.h b/apps/rf_sub1G/soream/config.h
new file mode 100644 (file)
index 0000000..e4d87ba
--- /dev/null
@@ -0,0 +1,45 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/config.h
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+#include "common.h"
+
+
+#define SELECTED_FREQ  FREQ_SEL_12MHz
+
+#define LPC_TIMER_PIN_CONFIG   (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL | LPC_IO_DRIVE_HIGHCURENT)
+
+
+/***************************************************************************** */
+void system_init(void);
+void read_user_data(void);
+void system_sleeping_shutdown(void);
+
+
+/******************************************************************************/
+void light_config(void);
+void set_light_on(void);
+
+
+
+
diff --git a/apps/rf_sub1G/soream/main.c b/apps/rf_sub1G/soream/main.c
new file mode 100644 (file)
index 0000000..c952d75
--- /dev/null
@@ -0,0 +1,85 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/main.c
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#include "common.h"
+
+#include "drivers/timers.h"
+#include "extdrv/status_led.h"
+
+#include "config.h"
+#include "rf.h"
+
+
+#define MODULE_VERSION 0x03
+#define MODULE_NAME "RF Sub1G - USB"
+
+
+/***************************************************************************** */
+int main(void)
+{
+       /* System clock and modules init */
+       system_init();
+
+       /* Static config */
+       read_user_data();
+
+       /* Radio */
+       rf_config();
+
+       /* Lights */
+       light_config();
+
+       /* Periodic requests */
+       add_systick_callback(announce_sys_up, 250);
+
+       while (1) {
+
+               /* Tell we are alive :) */
+               msleep(20);
+               watchdog_feed();
+
+               /* RF */
+               if (cc_tx == 1) {
+                       send_on_rf();
+               }
+
+               check_rf_state();
+
+               if (check_rx == 1) {
+                       check_rx = 0;
+                       if (handle_rf_rx_data() == 1) {
+                               set_light_on();
+                               stay_on = STAY_ON_RESET;
+                       }
+               }
+
+               if (stay_on == 0) {
+                       system_sleeping_shutdown();
+               }
+       }
+       return 0;
+}
+
+
+
+
diff --git a/apps/rf_sub1G/soream/rf.c b/apps/rf_sub1G/soream/rf.c
new file mode 100644 (file)
index 0000000..8910b10
--- /dev/null
@@ -0,0 +1,218 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/rf.c
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+
+#include "common.h"
+#include "drivers/gpio.h"
+#include "extdrv/cc1101.h"
+#include "rf.h"
+
+
+static uint8_t last_seq_sent = 0;
+static uint8_t last_seq_received = 0;
+static uint8_t last_seq_acked = 0;
+
+/* Check for received packet */
+int check_packet(struct packet* pkt)
+{
+       if (pkt->address != address) {
+               debug_printf("Bad address (%d/%d), not for us.\n", pkt->address, address);
+               return 0;
+       }
+       if (pkt->ack_num == last_seq_sent) {
+               last_seq_acked = 1;
+       }
+       last_seq_received = pkt->seq_num;
+       return 1;
+}
+
+
+/* Handle reception */
+/* Checks for valid packet and returns 1 if the light should be turned on */
+int handle_rf_rx_data(void)
+{
+       uint8_t data[RF_BUFF_LEN];
+       int8_t ret = 0;
+       uint8_t status = 0, sum = 0;
+
+       /* Check for received packet (and get it if any) */
+       memset(data, 0, RF_BUFF_LEN);
+       ret = cc1101_receive_packet(data, RF_BUFF_LEN, &status);
+       /* Go back to RX mode */
+       cc1101_enter_rx_mode();
+
+       /* Packet length */
+       if ((ret != (sizeof(struct packet) + 2)) || (status == 0)) {
+               static uint8_t cnt = 0; 
+               uint8_t pkt_status = 0;
+
+               debug_printf("RF: ret: %d, st: %d.\n", ret, status);
+               /* Need to de-assert rx interrupt by reading from the RX fifo even if it is empty */
+               ret = cc1101_handle_rx_err(&pkt_status);
+               debug_printf("RF: pkt_st: 0x%02x\n", pkt_status);
+               if (cnt == 0) {
+                       cnt++;
+                       check_rx = 1; /* Did we receive something anyway ? */
+               } else {
+                       cnt = 0;
+               }
+               return 0;
+       }
+
+       /* Compute and check packet checsum */
+       for (ret = 0; ret < sizeof(struct packet); ret++) {
+               sum += data[ret + 2];
+       }
+       if (sum != 0) {
+               debug_printf("Checksum error: %d\n", sum);
+               return 0;
+       }
+
+       ret = check_packet((struct packet*)(data + 2));
+
+       /* Got more data to be read ? */
+       status -= (sizeof(struct packet) + 4);
+       if (status > 0) {
+               check_rx = 1;
+       }
+
+       return ret;
+}
+
+volatile uint8_t cc_tx = 0;
+volatile uint8_t stay_on = STAY_ON_RESET;
+
+void announce_sys_up(uint32_t tick) {
+       cc_tx = 1;
+       if (stay_on > 0) {
+               stay_on--;
+       }
+}
+
+void send_on_rf(void)
+{
+       uint8_t cc_tx_data[RF_BUFF_LEN + 2];
+       struct packet* pkt = (struct packet*)(cc_tx_data + 2);
+       uint8_t tx_len = sizeof(struct packet);
+       uint8_t sum = 0;
+       uint8_t status = 0;
+       int ret = 0;
+
+       /* Prepare packet */
+       pkt->address = peer_address;
+       pkt->type = PKT_TYPE_LIGHT_ON;
+       pkt->checksum = 0;
+       pkt->seq_num = last_seq_sent + 1;
+       pkt->ack_num = last_seq_received;
+
+       /* Compute packet checksum */
+       for (ret = 0; ret < sizeof(struct packet); ret++) {
+               sum += cc_tx_data[ret + 2];
+       }
+       pkt->checksum = 0xFF - sum;
+       pkt->checksum += 1;
+
+       /* Prepare buffer header */
+       cc_tx_data[0] = tx_len + 1;
+       cc_tx_data[1] = peer_address;
+
+       /* Send */
+       if (cc1101_tx_fifo_state() != 0) {
+               cc1101_flush_tx_fifo();
+       }
+       ret = cc1101_send_packet(cc_tx_data, (tx_len + 2));
+       if (ret != (tx_len + 2)) {
+               debug_printf("Tx ret: %d\n", ret);
+       }
+
+       last_seq_sent++;
+
+       /* Do not leave radio in an unknown or unwated state */
+       do {
+               status = (cc1101_read_status() & CC1101_STATE_MASK);
+       } while (status == CC1101_STATE_TX);
+}
+
+
+void check_rf_state(void)
+{
+       uint8_t status = 0;
+
+       status = (cc1101_read_status() & CC1101_STATE_MASK);
+       if (status != CC1101_STATE_RX) {
+               static uint8_t loop = 0;
+               loop++;
+               if (loop > 10) {
+                       if (cc1101_rx_fifo_state() != 0) {
+                               cc1101_flush_rx_fifo();
+                       }
+                       cc1101_enter_rx_mode();
+                       loop = 0;
+               }
+       }
+}
+
+/******************************************************************************/
+/* RF Configuration */
+
+uint8_t address = 0;
+uint8_t peer_address = 0;
+
+volatile uint8_t check_rx = 0;
+void rf_rx_calback(uint32_t gpio)
+{
+       check_rx = 1;
+}
+
+static uint8_t rf_specific_settings[] = {
+       CC1101_REGS(gdo_config[2]), 0x07, /* GDO_0 - Assert on CRC OK | Disable temp sensor */
+       CC1101_REGS(radio_stm[1]), 0x3F, /* CCA mode "if RSSI below threshold", Stay in RX, Go to RX (page 81) */
+       CC1101_REGS(pkt_ctrl[0]), 0x0F, /* Accept all sync, CRC err auto flush, Append, Addr check and Bcast */
+#if (RF_915MHz == 1)
+       /* FIXME : Add here a define protected list of settings for 915MHz configuration */
+#endif
+};
+
+
+const struct pio cc1101_cs_pin = LPC_GPIO_0_15;
+const struct pio cc1101_miso_pin = LPC_SSP0_MISO_PIO_0_16;
+const struct pio cc1101_gdo0 = LPC_GPIO_0_6;
+
+/* RF config */
+void rf_config(void)
+{
+       config_gpio(&cc1101_gdo0, LPC_IO_MODE_PULL_UP, GPIO_DIR_IN, 0);
+       cc1101_init(0, &cc1101_cs_pin, &cc1101_miso_pin); /* ssp_num, cs_pin, miso_pin */
+       /* Set default config */
+       cc1101_config();
+       /* And change application specific settings */
+       cc1101_update_config(rf_specific_settings, sizeof(rf_specific_settings));
+       set_gpio_callback(rf_rx_calback, &cc1101_gdo0, EDGE_RISING);
+
+       cc1101_set_address(address);
+       cc1101_send_calibration_request();
+       debug_printf("CC1101 RF link init done.\n");
+}
+
+
+
diff --git a/apps/rf_sub1G/soream/rf.h b/apps/rf_sub1G/soream/rf.h
new file mode 100644 (file)
index 0000000..70f0ce0
--- /dev/null
@@ -0,0 +1,58 @@
+/****************************************************************************
+ *   apps/rf_sub1G/soream/rf.h
+ *
+ * sub1G_module support code - USB version
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#include "common.h"
+
+
+#define RF_BUFF_LEN  64
+
+/* Packet */
+struct packet {
+       char address;   /* Destination of paquet */
+       uint8_t type;   /* Packet type */
+       uint8_t checksum; /* Checksum */
+       uint8_t seq_num; /* Packet sequence number */
+       uint8_t ack_num; /* Packet acknoledge number */
+} __attribute__ ((__packed__));
+
+#define PKT_TYPE_LIGHT_ON  0x2C  /* Arbitrary value */
+
+int handle_rf_rx_data(void);
+
+void check_rf_state(void);
+
+void send_on_rf(void);
+
+void announce_sys_up(uint32_t tick);
+
+/***************************************************************************** */
+/* RF config */
+#define RF_868MHz  1
+#define RF_915MHz  0
+#if ((RF_868MHz) + (RF_915MHz) != 1)
+#error Either RF_868MHz or RF_915MHz MUST be defined.
+#endif
+
+void rf_config(void);
+
+