desloges-libioulle / Mbed 2 deprecated app3_coordinator

Dependencies:   mbed-rtos mbed EthernetInterface

Revision:
0:671a7b7e4673
Child:
2:ff0b74e5e62c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Feb 12 16:07:11 2017 +0000
@@ -0,0 +1,365 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "xbee.h"
+
+#define nullptr 0
+
+DigitalOut myled(LED1);
+
+Serial pc(USBTX, USBRX);
+
+Serial *xbee;
+DigitalOut *xbeeRst;
+
+const int HARDWARE_RESET_SIGNAL =      0x10;
+const int COORDINATOR_STARTED_SIGNAL = 0x20;
+const int TICKER_SIGNAL =              0x40;
+const int RESPONSE_SIGNAL =            0x80;
+
+Thread * XBeeConsumer;
+Thread * XBeeProducer;
+Thread * EventConsumer;
+Ticker timer;
+
+int responseStatus;
+
+char * BTN_ID = "BTN";
+char * ACC_ID = "ACC";
+
+struct ButtonEvent{
+    char id[3];
+    bool state;
+};
+
+struct AccelerometerEvent {
+    char id[3];
+    char x[2], y[2], z[2];
+};
+
+MemoryPool<ButtonEvent, 32> btnPool;
+MemoryPool<AccelerometerEvent, 32> accPool;
+Queue<void, 64> event;
+
+struct Rooter{
+    long long int addr64;
+    short addr16;
+    
+    bool operator==(const Rooter & rhs){
+        return addr64 == rhs.addr64 && addr16 == rhs.addr16;
+    }
+};
+
+#define ROOTER_MAX 2
+Rooter rooters[ROOTER_MAX];
+int rooterCount = 0;
+/*******************************************************/
+/**********************UTILITIES************************/
+/*******************************************************/
+
+PinName GetPinName(const int p){
+    switch(p){
+        case 5: return p5;
+        case 6: return p6;
+        case 7: return p7;
+        case 8: return p8;
+        case 9: return p9;
+        case 10: return p10;
+        case 11: return p11;
+        case 12: return p12;
+        case 13: return p13;
+        case 14: return p14;
+        case 15: return p15;
+        case 16: return p16;
+        case 17: return p17;
+        case 18: return p18;
+        case 19: return p19;
+        case 20: return p20;
+        case 21: return p21;
+        case 22: return p22;
+        case 23: return p23;
+        case 24: return p24;
+        case 25: return p25;
+        case 26: return p26;
+        case 27: return p27;
+        case 28: return p28;
+        case 29: return p29;
+        case 30: return p30;
+    }
+    pc.printf("Numero de pin invalid");
+    return NC;
+}
+
+/*******************************************************/
+/***********************CONFIG**************************/
+/*******************************************************/
+int panID;
+int xbeeTxPin;
+int xbeeRxPin;
+int xbeeRstPin;
+char server[16];
+
+char key[10];
+
+LocalFileSystem local("local");
+
+void ReadConfig(){
+    memset(server, 0x00, 16);
+    FILE * f = fopen("/local/coord.cfg", "r");
+    fscanf(f,"%s %x", key, &panID);
+    pc.printf("Config started\r\n");
+    pc.printf("Lecture de la config %s : %04x\r\n", key, panID);
+    fscanf(f,"%s %d %d %d", key, &xbeeTxPin, &xbeeRxPin, &xbeeRstPin);
+    pc.printf("Lecture de la config %s : %d %d %d\r\n", key, xbeeTxPin, xbeeRxPin, xbeeRstPin);
+    fscanf(f,"%s %s", key, server);
+    pc.printf("Lecture de la config %s : %s\r\n", key, server);
+    fclose(f);
+}
+
+/*******************************************************/
+/**********************XBEE SEND************************/
+/*******************************************************/
+
+char frameID = 0;
+
+inline char GetFrameID(){
+    ++frameID;
+    if (frameID == 0){
+        frameID = 1;
+    }
+    return frameID;
+}
+
+void SetCheckSum(char * buffer){
+    uint16_t length = GetFrameLength(buffer);
+    
+    char sum = 0;
+    
+    int max = length + 3;
+    
+    for(int i = 3; i < max; ++i){
+        sum += buffer[i];
+    }
+    
+    buffer[max] = 0xff - sum;
+}
+
+void XBeeSend(char * buffer, int count){
+    for ( int i = 0; i < count; ++i ){
+        xbee->putc(buffer[i]);
+    }
+}
+
+void XBeeSendATCommand(bool queue, char * type, char * data, int dataLength){
+    char buffer[128];
+    buffer[START_IDX] = START;
+    buffer[LENGTH_MSB_IDX] = (dataLength + AT_MIN_SIZE) >> 8;
+    buffer[LENGTH_LSB_IDX] = (dataLength + AT_MIN_SIZE) & 0xff;
+    buffer[API_ID_IDX] = queue ? API_ID_AT_CMD_QUEUE : API_ID_AT_CMD;
+    buffer[FRAME_ID_IDX] = GetFrameID();
+    memcpy(&buffer[AT_CMD_ID_IDX], type, AT_CMD_ID_SIZE);
+    memcpy(&buffer[AT_PARAM_IDX], data, dataLength);
+    
+    SetCheckSum(buffer);
+    
+    if (!ValidateCheckSum(buffer)){
+        pc.printf("CheckSum problem\r\n");
+    }
+    
+    while(true){
+        XBeeSend(buffer, dataLength + AT_MIN_SIZE + FRAME_MIN_SIZE);
+    
+        Thread::signal_wait(RESPONSE_SIGNAL);
+        
+        switch (responseStatus){
+        case AT_CMD_RSP_STATUS_OK:
+            return;
+        case AT_CMD_RSP_STATUS_ERROR:
+        case AT_CMD_RSP_STATUS_INVALID_CMD:
+        case AT_CMD_RSP_STATUS_INVALID_PARAM:
+        case AT_CMD_RSP_STATUS_TX_FAILURE:
+        default:
+            pc.printf("This AT error occured : %02x\r\n", responseStatus);
+            break;
+        }
+    }
+}
+
+inline void XBeeSendATID(){
+    char idBuf[8];
+    for (int i = 0; i < 8; ++i){
+        idBuf[i] = (panID >> (56 - 8 * i)) & 0xff;
+    }
+    XBeeSendATCommand(true, "ID", idBuf, 8);
+}
+
+inline void XBeeSendATWR(){
+    XBeeSendATCommand(true, "WR", nullptr, 0);
+}
+
+inline void XBeeSendATAC(){
+    XBeeSendATCommand(true, "AC", nullptr, 0);
+}
+
+/*******************************************************/
+/**********************XBEE READ************************/
+/*******************************************************/
+
+void HandleBtnPacket(char* cmd){
+    ButtonEvent* evt = btnPool.alloc();
+    memcpy(evt->id, BTN_ID, 3);
+    evt->state = cmd[RECEIVED_PACKET_DATA_IDX + 3] == 0x01;
+    event.put((void*)evt);
+}
+
+void HandleAccPacket(char* cmd){
+    AccelerometerEvent* evt = accPool.alloc();
+    memcpy(evt->id, ACC_ID, 3);
+    memcpy(evt->x, &cmd[RECEIVED_PACKET_DATA_IDX + 3], 2);
+    memcpy(evt->y, &cmd[RECEIVED_PACKET_DATA_IDX + 5], 2);
+    memcpy(evt->z, &cmd[RECEIVED_PACKET_DATA_IDX + 7], 2);
+    event.put((void*)evt);
+}
+
+void HandleXbeeReceivedPacket(char * cmd){
+    if (cmd[RECEIVED_PACKET_DATA_IDX] == BTN_ID[0] && 
+        cmd[RECEIVED_PACKET_DATA_IDX + 1] == BTN_ID[1] && 
+        cmd[RECEIVED_PACKET_DATA_IDX + 2] == BTN_ID[2]){
+        HandleBtnPacket(cmd);
+    }
+    
+    if (cmd[RECEIVED_PACKET_DATA_IDX] == ACC_ID[0] && 
+        cmd[RECEIVED_PACKET_DATA_IDX + 1] == ACC_ID[1] && 
+        cmd[RECEIVED_PACKET_DATA_IDX + 2] == ACC_ID[2]){
+        HandleAccPacket(cmd);
+    }
+}
+
+void HandleXbeeModemStatus(char * cmd){
+    switch(cmd[MODEM_STATUS_STATUS_IDX]){
+    case MODEM_STATUS_HARDWARE_RST:
+        XBeeProducer->signal_set(HARDWARE_RESET_SIGNAL);
+        break;
+    case MODEM_STATUS_COORDINATOR_STARTED:
+        XBeeProducer->signal_set(COORDINATOR_STARTED_SIGNAL);
+        break;
+    default:
+        pc.printf("Unhandled modem status received : %02x\r\n", cmd[MODEM_STATUS_STATUS_IDX]);
+        break;
+    }
+}
+
+void HandleXBeeATCommandResponse(char * cmd){
+    responseStatus = cmd[AT_CMD_RSP_STATUS_IDX];
+    XBeeProducer->signal_set(RESPONSE_SIGNAL);
+}
+
+void HandleXbeeReceivedCommand(char * cmd){
+    switch(cmd[API_ID_IDX]){
+    case API_ID_AT_CMD_RSP:
+        HandleXBeeATCommandResponse(cmd);
+        break;
+    case API_ID_MODEM_STATUS:
+        HandleXbeeModemStatus(cmd);
+        break;
+    default:
+        pc.printf("Unhandle XBee Command received : %02x\r\n", cmd[API_ID_IDX]);
+    }
+}
+
+/*******************************************************/
+/************************INIT***************************/
+/*******************************************************/
+
+bool InitXBee(){
+    xbeeRst->write(0);
+    wait(0.4);
+    xbeeRst->write(1);
+    
+    Thread::signal_wait(HARDWARE_RESET_SIGNAL);
+    
+    XBeeSendATID();
+    XBeeSendATWR();
+    XBeeSendATAC();
+    
+    Thread::signal_wait(COORDINATOR_STARTED_SIGNAL);
+     
+    pc.printf("XBee configured\r\n");
+    
+    return true;
+}
+
+void ConsumerMain(){
+    char buffer[128];
+    while(true){
+        while(!xbee->readable()){
+            continue;
+        }
+        buffer[START_IDX] = xbee->getc();
+        if (buffer[START_IDX] != START){
+            pc.printf("Wrong start byte received : %02x\r\n", buffer[START_IDX]);
+            continue;
+        }
+        buffer[LENGTH_MSB_IDX] = xbee->getc();
+        buffer[LENGTH_LSB_IDX] = xbee->getc();
+        int length = GetFrameLength(buffer);
+        
+        for (int i = 0; i <= length; ++i){
+            buffer[i + API_ID_IDX] = xbee->getc();
+        }
+        if (!ValidateCheckSum(buffer)){
+            pc.printf("Bad CheckSum : %02x\r\n", buffer[length + FRAME_MIN_SIZE - 1]);
+            continue;
+        }
+        
+        HandleXbeeReceivedCommand(buffer);
+    }
+}
+
+bool ProducerInit(){
+    if (!InitXBee()){
+        pc.printf("Connection problem with the XBee\r\n");
+        return false;
+    }
+    
+    return true;
+}
+
+void Tick(){
+    XBeeProducer->signal_set(TICKER_SIGNAL);
+}
+
+void ProducerMain(const void*){
+    if (!ProducerInit()){
+        pc.printf("Initialization problem\r\n");
+        return;
+    }
+    
+    timer.attach(&Tick, 1);
+    
+    while(true){
+        Thread::signal_wait(TICKER_SIGNAL);
+        // Send Remote AT Command
+    }
+}
+
+int main() {
+    // Lecture de la configuration.
+    ReadConfig();
+    
+    //Créer les interfaces de communication des capteurs avec les données de la config.
+    Serial mainXbee(GetPinName(xbeeTxPin), GetPinName(xbeeRxPin));
+    DigitalOut mainXbeeRst(GetPinName(xbeeRstPin));
+    
+    //Rendre les interfaces de communication globaux.
+    xbee = &mainXbee;
+    xbeeRst = &mainXbeeRst;
+    
+    Thread consumer(ConsumerMain);
+    XBeeConsumer = &consumer;
+    
+    Thread producer(ProducerMain);
+    XBeeProducer = &producer;
+    
+    // Mettre la thread principale dans un état de waiting à l'infinie
+    Thread::signal_wait(0x1);
+}