-
-
Save irevoire/fc300e03aa631d1bd24b58361787165a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <platform.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <printf.h> | |
#include <string.h> | |
#include <time.h> | |
#include "phy.h" | |
#include "soft_timer.h" | |
#include "event.h" | |
#ifdef IOTLAB_M3 | |
#include "lps331ap.h" | |
#include "isl29020.h" | |
#endif | |
#include "iotlab_uid.h" | |
#include "mac_csma.h" | |
#include "phy.h" | |
#include "iotlab_i2c.h" | |
#include "iotlab_uid_num_hashtable.h" | |
// choose channel in [11-26] | |
#define CHANNEL 11 | |
#define RADIO_POWER PHY_POWER_0dBm | |
#define ADDR_BROADCAST 0xFFFF | |
// UART callback function | |
static void char_rx(handler_arg_t arg, uint8_t c); | |
static void handle_cmd(handler_arg_t arg); | |
// timer alarm function | |
static void alarm(handler_arg_t arg); | |
static soft_timer_t tx_timer; | |
#define BLINK_PERIOD soft_timer_s_to_ticks(1) | |
/* Global variables */ | |
// print help every second | |
volatile int8_t print_help = 1; | |
volatile int8_t leds_active = 1; | |
#ifdef IOTLAB_M3 | |
/** | |
* Sensors | |
*/ | |
static void temperature_sensor() | |
{ | |
int16_t value; | |
lps331ap_read_temp(&value); | |
printf("Chip temperature measure: %f\n", 42.5 + value / 480.0); | |
} | |
static void light_sensor() | |
{ | |
float value = isl29020_read_sample(); | |
printf("Luminosity measure: %f lux\n", value); | |
} | |
static void pressure_sensor() | |
{ | |
uint32_t value; | |
lps331ap_read_pres(&value); | |
printf("Pressure measure: %f mabar\n", value / 4096.0); | |
} | |
#endif | |
/** | |
* Node UID | |
*/ | |
static void print_node_uid() | |
{ | |
uint16_t node_uid = iotlab_uid(); | |
struct node node = node_from_uid(node_uid); | |
printf("Current node uid: %04x (%s-%u)\n", | |
node_uid, node.type_str, node.num); | |
} | |
/** | |
* Control Node interaction | |
*/ | |
static void print_cn_time() | |
{ | |
// Query control node time | |
struct soft_timer_timeval time; | |
if (iotlab_get_time(&time)) { | |
printf("Error while getting Control node time\n"); | |
return; | |
} | |
struct tm *local_time = gmtime((time_t *)&time.tv_sec); | |
char date_str[64]; | |
strftime(date_str, (sizeof date_str), "%Y-%m-%d %H:%M:%S", local_time); | |
printf("Control Node time: %u.%06u. Date is: UTC %s.%06u\n", | |
time.tv_sec, time.tv_usec, date_str, time.tv_usec); | |
} | |
/* * Radio config | |
*/ | |
static void send_packet() | |
{ | |
uint16_t ret; | |
static uint8_t num = 0; | |
static char packet[PHY_MAX_TX_LENGTH - 4]; // 4 for mac layer | |
uint16_t length; | |
// max pkt length <= max(cc2420, cc1101) | |
snprintf(packet, sizeof(packet), "Hello World!: %u", num++); | |
length = 1 + strlen(packet); | |
ret = mac_csma_data_send(ADDR_BROADCAST, (uint8_t *)packet, length); | |
printf("\nradio > "); | |
if (ret != 0) | |
printf("Packet sent\n"); | |
else | |
printf("Packet sent failed\n"); | |
} | |
static void send_packet_calc() | |
{ | |
uint16_t ret, length; | |
static char packet[PHY_MAX_TX_LENGTH - 4]; | |
snprintf(packet, sizeof(packet), "BOINC: 4+2"); | |
length = 1 + strlen(packet); | |
ret = mac_csma_data_send(ADDR_BROADCAST, (uint8_t *)packet, length); | |
printf("\nradio >"); | |
if (ret != 0) | |
printf("Packet send\n"); | |
else | |
printf("Packet sent failed\n"); | |
} | |
static void send_temp_packet_broadcast() | |
{ | |
uint16_t ret, length; | |
int16_t temp; | |
static char packet[PHY_MAX_TX_LENGTH - 4]; | |
lps331ap_read_temp(&temp); | |
snprintf(packet, sizeof(packet), "%f", 42.5 + temp / 480.0); | |
length = 1 + strlen(packet); | |
ret = mac_csma_data_send(ADDR_BROADCAST, (uint8_t *)packet, length); | |
if (ret != 0) | |
printf("Packet sent\n"); | |
else | |
printf("Packet sent failed\n"); | |
} | |
uint16_t master_addr = 0; | |
static void send_temp_packet_master() | |
{ | |
uint16_t ret, length; | |
int16_t temp; | |
static char packet[PHY_MAX_TX_LENGTH - 4]; | |
lps331ap_read_temp(&temp); | |
snprintf(packet, sizeof(packet), "%f", 42.5 + temp / 480.0); | |
length = 1 + strlen(packet); | |
if (!master_addr) | |
return; | |
ret = mac_csma_data_send(master_addr, (uint8_t *)packet, length); | |
if (ret != 0) | |
printf("Packet sent\n"); | |
else | |
printf("Packet sent failed\n"); | |
} | |
static void start_election_proccess() | |
{ | |
uint16_t node_uid = iotlab_uid(); | |
uint8_t data[11] = {'E', 'L', 'E', 'C', ':', ' ', 42, 42, 42, 42, 42}; | |
printf("uid = %x\n", node_uid); | |
snprintf((char *)data + 6, 5, "%x", node_uid); | |
int ret = mac_csma_data_send(ADDR_BROADCAST, data, 12); | |
if (ret != 0) | |
printf("Packet sent!\n"); | |
else | |
printf("Packet sent failed\n"); | |
} | |
static void send_big_packet() | |
{ | |
uint16_t ret; | |
static uint8_t num = 0; | |
static char packet[PHY_MAX_TX_LENGTH - 4]; // 4 for mac layer | |
static char pluspack[40]="012345678901234567890123456789012345678\0"; | |
uint16_t length; | |
snprintf(packet, sizeof(packet), "Big Hello World!: %u %s",num++, pluspack); | |
length = 1 + strlen(packet); | |
ret = mac_csma_data_send(ADDR_BROADCAST, (uint8_t *)packet, length); | |
if (!ret) { | |
printf("Failed to send packet\n"); | |
} | |
printf("\nradio > "); | |
if (ret != 0) | |
printf("Big packet sent\n"); | |
else | |
printf("Big packet sent failed\n"); | |
} | |
void mac_csma_data_received(uint16_t src_addr, | |
const uint8_t *data, uint8_t length, int8_t rssi, uint8_t lqi) | |
{ | |
const char start[] = "ELEC: "; | |
if (strncmp((const char *)data, start, sizeof(start) - 1) == 0) | |
{ | |
uint16_t node_uid = iotlab_uid(); | |
uint16_t remote_uid = strtol((const char *)data + sizeof(start) - 1, NULL, 16); | |
if (node_uid < remote_uid) | |
{ | |
printf("Found a new master %x\n", remote_uid); | |
master_addr = remote_uid; | |
} | |
else | |
{ | |
printf("I'm better than %x\n", remote_uid); | |
} | |
} | |
printf("Got %s from %x\n", (const char*)data, src_addr); | |
} | |
/** | |
* Leds action | |
*/ | |
static void leds_action() | |
{ | |
printf("\nleds > "); | |
if (leds_active) { | |
// The alarm timer looses the hand | |
leds_active = 0; | |
// Switch off the LEDs | |
leds_off(LED_0 | LED_1 | LED_2); | |
printf("off\n"); | |
} else { | |
// The alarm timer takes the hand | |
leds_active = 1; | |
printf("blinking\n"); | |
} | |
} | |
/* | |
* HELP | |
*/ | |
static void print_usage() | |
{ | |
printf("\n\nIoT-LAB Simple Demo program\n"); | |
printf("Type command\n"); | |
printf("\th:\tprint this help\n"); | |
#ifdef IOTLAB_M3 | |
printf("\tt:\ttemperature measure\n"); | |
printf("\tl:\tluminosity measure\n"); | |
printf("\tp:\tpressure measure\n"); | |
#endif | |
printf("\tu:\tprint node uid\n"); | |
printf("\td:\tread current date using control_node\n"); | |
printf("\ts:\tsend a radio packet\n"); | |
printf("\tb:\tsend a big radio packet\n"); | |
printf("\te:\ttoggle leds blinking\n"); | |
if (print_help) | |
printf("\n Type Enter to stop printing this help\n"); | |
} | |
static void hardware_init() | |
{ | |
// Openlab platform init | |
platform_init(); | |
event_init(); | |
soft_timer_init(); | |
// Switch off the LEDs | |
leds_off(LED_0 | LED_1 | LED_2); | |
// Uart initialisation | |
uart_set_rx_handler(uart_print, char_rx, NULL); | |
#ifdef IOTLAB_M3 | |
// ISL29020 light sensor initialisation | |
isl29020_prepare(ISL29020_LIGHT__AMBIENT, ISL29020_RESOLUTION__16bit, | |
ISL29020_RANGE__16000lux); | |
isl29020_sample_continuous(); | |
// LPS331AP pressure sensor initialisation | |
lps331ap_powerdown(); | |
lps331ap_set_datarate(LPS331AP_P_12_5HZ_T_12_5HZ); | |
#endif | |
// Init csma Radio mac layer | |
mac_csma_init(CHANNEL, RADIO_POWER); | |
// Init control_node i2c | |
iotlab_i2c_init(); | |
// Initialize a openlab timer | |
soft_timer_set_handler(&tx_timer, alarm, NULL); | |
soft_timer_start(&tx_timer, BLINK_PERIOD, 1); | |
} | |
static void handle_cmd(handler_arg_t arg) | |
{ | |
switch ((char) (uint32_t) arg) { | |
#ifdef IOTLAB_M3 | |
case 't': | |
temperature_sensor(); | |
break; | |
case 'l': | |
light_sensor(); | |
break; | |
case 'p': | |
pressure_sensor(); | |
break; | |
#endif | |
case 'u': | |
print_node_uid(); | |
break; | |
case 'd': | |
print_cn_time(); | |
break; | |
case 's': | |
send_packet(); | |
break; | |
case 'b': | |
send_big_packet(); | |
break; | |
case 'e': | |
leds_action(); | |
break; | |
case 'c': | |
send_packet_calc(); | |
break; | |
case 'w': | |
send_temp_packet_broadcast(); | |
break; | |
case 'z': | |
send_temp_packet_master(); | |
break; | |
case 'j': | |
start_election_proccess(); | |
break; | |
case '\n': | |
printf("\ncmd > "); | |
break; | |
case 'h': | |
default: | |
print_usage(); | |
break; | |
} | |
} | |
int main() | |
{ | |
hardware_init(); | |
platform_run(); | |
return 0; | |
} | |
/* Reception of a char on UART and store it in 'cmd' */ | |
static void char_rx(handler_arg_t arg, uint8_t c) | |
{ | |
// disable help message after receiving char | |
print_help = 0; | |
event_post_from_isr(EVENT_QUEUE_APPLI, handle_cmd, | |
(handler_arg_t)(uint32_t) c); | |
} | |
static void alarm(handler_arg_t arg) | |
{ | |
if (leds_active) | |
leds_toggle(LED_0 | LED_1 | LED_2); | |
/* Print help before getting first real \n */ | |
if (print_help) { | |
event_post(EVENT_QUEUE_APPLI, handle_cmd, (handler_arg_t) 'h'); | |
event_post(EVENT_QUEUE_APPLI, handle_cmd, (handler_arg_t) '\n'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment