App1_S5
/
APP4_IRQ
APP4 S5
radio.cpp
- Committer:
- Cheroukee
- Date:
- 2017-10-12
- Revision:
- 8:a878763b0ae3
- Parent:
- 7:d25bcde7dcf1
- Child:
- 9:081324663b8c
File content as of revision 8:a878763b0ae3:
#include "radio.h" #include "mbed.h" #include "rtos.h" #include <LPC17xx.h> #define MESSAGE_BUFFER_SIZE 16 #define MANCHESTER_SPEED_OUT 10 #define INPUT_RADIO p18 #define OUTPUT_RADIO p6 radio_message_t out_messages[MESSAGE_BUFFER_SIZE]; byte out_message_in; byte out_message_out; radio_message_t in_messages[MESSAGE_BUFFER_SIZE]; byte in_message_in; byte in_message_out; InterruptIn input(INPUT_RADIO); RtosTimer out_timer(radio_out, osTimerPeriodic, (void *)out_messages); DigitalOut output(OUTPUT_RADIO); #ifdef LED DigitalOut in_debug_led(LED4); DigitalOut out_debug_led(LED3); DigitalOut frame_end_led(LED2); DigitalOut frame_in_end_led(LED1); #endif Serial PC(USBTX, USBRX); // API functions void init_radio_system() { setup_radio_in(); setup_radio_out(); output = 0; } // Private functions typedef enum { in_attente = 0, in_preambule, in_data, in_idle } receive_state_t; DigitalOut led4(LED4); DigitalOut led3(LED3); DigitalOut led2(LED2); DigitalOut led1(LED1); byte current_state = in_attente; byte current_byte_progress = 0; void stop_frame(void const *n); RtosTimer ticker_watch(stop_frame, osTimerPeriodic, NULL); Thread thread; void stop_frame(void const *n) { //frame_in_end_led = 0; current_state = in_attente; current_byte_progress = 0; ticker_watch.stop(); } volatile int t = 0; volatile int c = 0; void radio_in() { static Timer timer; static int t_half = 0; static byte current_byte = 0; //in_debug_led = !in_debug_led; switch (current_state) { case in_attente: { //led4 = 0; led3 = 0; led2 = 0; led1 = 0; //frame_in_end_led = 0; if (input == 1) { led1 = 1; timer.start(); current_state = in_preambule; current_byte_progress = 1; //frame_in_end_led = 1; } break; } case in_preambule: { led2 = 1; current_byte_progress++; t = timer.read_ms(); timer.reset(); if (current_byte_progress > 7) { t_half = t / 2; ticker_watch.start(t + t_half); current_byte_progress = 0; current_state = in_data; c = t; thread.signal_set(0x1); } break; } case in_data: { led3 = 1; if(timer.read_ms() > t + t_half) { led4 = 1; //frame_in_end_led = 0; current_state = in_attente; current_byte_progress = 0; timer.stop(); timer.reset(); } else if (timer.read_ms() > t_half) { current_byte = (!input << (7 - current_byte_progress)) | current_byte; current_byte_progress++ ; //PC.putc(input); // Display data //frame_in_end_led = !input; ticker_watch.start(t + t_half); timer.reset(); if (current_byte_progress > 7) { c = current_byte; thread.signal_set(0x1); current_byte = 0; current_byte_progress = 0; } } else { //ticker_watch.start(t + t_half); } break; } case in_idle: { led4 = 1; //frame_in_end_led = 0; current_state = in_attente; current_byte_progress = 0; break; } } } void thread_putc() { while(1) { Thread::signal_wait(0x1); PC.printf("0x%x\n\r", c); } } void setup_radio_in() { in_message_in = 0; in_message_out = 0; thread.start(callback(thread_putc)); input.rise(&radio_in); input.fall(&radio_in); } void setup_radio_out() { out_message_in = 0; out_message_out = 0; //out_debug_led = 0; //frame_end_led = 1; ////////////////////////////////////////////////////// // Creation d'un message et insertion dans le buffer radio_message_t* message = (out_messages + out_message_in); message->preambule = HEADER_DELIMITER; message->start = HEADER_START; message->options = HEADER_DELIMITER; message->length = 0x3; message->data[0] = 0xC0; message->data[1] = 0xFF; message->data[2] = 0xEE; // Ajouter calcul message->control = 0xCE; message->end = FOOTER_END; // On avance dans le buffer; out_message_in++; ////////////////////////////////////////////////////// output = 0; wait(1); out_timer.start(MANCHESTER_SPEED_OUT); } typedef enum { preambule = 0, start, options, length, data, crc, end, idle } out_state_t; void radio_out(void const *args) { static byte current_byte_progress = 0; static byte current_byte = 0; static byte out_current_state = 0; static bool IsBitTransition = false; static byte next_value = 0; radio_message_t* message = (radio_message_t*)(out_messages + out_message_out); #define OUTPUT_HIGH output = 1; #define OUTPUT_LOW output = 0; #define SET_VAL_BIT_MASK(val) next_value = 0x1 & val; #define SET_VAL_SHIFT(val, shift) SET_VAL_BIT_MASK(val >> (7 - shift)) #define CHECK_NEXT_STATE if (current_byte_progress > 7) \ { \ out_current_state++; \ current_byte_progress = 0; \ } //out_debug_led = !out_debug_led; if (!IsBitTransition) { // Dependant du state, on progresse dans l'envoi du message switch (out_current_state) { case preambule: // preambule { SET_VAL_SHIFT(message->preambule, current_byte_progress++); CHECK_NEXT_STATE break; } case start: // start { SET_VAL_SHIFT(message->start, current_byte_progress++); CHECK_NEXT_STATE break; } case options: // entete options { SET_VAL_SHIFT(message->options, current_byte_progress++); CHECK_NEXT_STATE break; } case length: // entete lenght { SET_VAL_SHIFT(message->length, current_byte_progress++); CHECK_NEXT_STATE break; } case data: // charge utile { SET_VAL_SHIFT(message->data[current_byte], current_byte_progress++) if (current_byte_progress > 7) { current_byte++; current_byte_progress = 0; if (current_byte >= message->length) { current_byte = 0; out_current_state++; } } //CHECK_NEXT_STATE break; } case crc: // controle { SET_VAL_SHIFT(message->control, current_byte_progress++); CHECK_NEXT_STATE break; } case end: // end { SET_VAL_SHIFT(message->end, current_byte_progress++); CHECK_NEXT_STATE break; } case idle: { //current_state = 0; current_byte = 0; current_byte_progress = 0; break; } } if (next_value != output && out_current_state != idle) { output = !output; } if (out_current_state > end) { //frame_end_led = 0; //out_current_state = preambule; } } else if (out_current_state != idle) { output = !output; } IsBitTransition = !IsBitTransition; }