App1_S5
/
APP4_IRQ
APP4 S5
radio.cpp
- Committer:
- Cheroukee
- Date:
- 2017-10-12
- Revision:
- 9:081324663b8c
- Parent:
- 8:a878763b0ae3
- Child:
- 10:c4629b6c42f8
File content as of revision 9:081324663b8c:
#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); #ifndef LED DigitalOut in_debug_led4(LED4); DigitalOut out_debug_led3(LED3); DigitalOut frame_out_end_led2(LED2); DigitalOut frame_in_end_led1(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; int start_speed = MANCHESTER_SPEED_OUT; 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_led1 = 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_led4 = !in_debug_led4; switch (current_state) { case in_attente: { frame_in_end_led1 = 0; if (input == 1) { timer.start(); current_state = in_preambule; current_byte_progress = 1; frame_in_end_led1 = 1; } break; } case in_preambule: { 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: { if(timer.read_ms() > t + t_half) { frame_in_end_led1 = 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 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: { frame_in_end_led1 = 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_led3 = 0; frame_out_end_led2 = 0; ////////////////////////////////////////////////////// // 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(start_speed); } typedef enum { out_preambule = 0, out_start, out_options, out_length, out_data, out_crc, out_end, out_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_led3 = !out_debug_led3; if (!IsBitTransition) { // Dependant du state, on progresse dans l'envoi du message switch (out_current_state) { case out_preambule: // preambule { frame_out_end_led2 = 1; SET_VAL_SHIFT(message->preambule, current_byte_progress++); CHECK_NEXT_STATE break; } case out_start: // start { SET_VAL_SHIFT(message->start, current_byte_progress++); CHECK_NEXT_STATE break; } case out_options: // entete options { SET_VAL_SHIFT(message->options, current_byte_progress++); CHECK_NEXT_STATE break; } case out_length: // entete lenght { SET_VAL_SHIFT(message->length, current_byte_progress++); CHECK_NEXT_STATE break; } case out_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 out_crc: // controle { SET_VAL_SHIFT(message->control, current_byte_progress++); CHECK_NEXT_STATE break; } case out_end: // end { SET_VAL_SHIFT(message->end, current_byte_progress++); CHECK_NEXT_STATE break; } case out_idle: { //current_state = 0; current_byte = 0; current_byte_progress = 0; break; } } // Changement d'etat pour permettre de faire la bonne transition de valeur if (next_value != output && out_current_state != out_idle) { output = !output; } // Si on est a la fin du packet, on retourne au debut et on reenvoye les donnees if (out_current_state > out_end) { frame_out_end_led2 = 0; out_current_state = out_preambule; out_timer.stop(); start_speed += 1; out_timer.start(start_speed); } } // Si on est pas dans une transitipon else if (out_current_state != out_idle) { output = !output; } IsBitTransition = !IsBitTransition; }