desloges-libioulle / Mbed 2 deprecated app3_router

Dependencies:   mbed-rtos mbed

Revision:
0:0545bc9f81e0
diff -r 000000000000 -r 0545bc9f81e0 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Feb 12 16:06:13 2017 +0000
@@ -0,0 +1,442 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "xbee.h"
+
+#define nullptr 0
+
+DigitalOut led1(LED1);
+
+Serial pc(USBTX, USBRX);
+
+DigitalIn * btn;
+I2C * acc;
+Serial *xbee;
+DigitalOut *xbeeRst;
+
+Mutex xbeeMutex;
+
+int ReadButton(char*);
+int ReadAccelerometer(char*);
+
+const uint8_t DEVICE_COUNT = 2;
+
+int (* readFunctions[DEVICE_COUNT]) (char *) = {&ReadButton, &ReadAccelerometer};
+
+const int HARDWARE_RESET_SIGNAL = 0x10;
+const int JOINED_NETWORK_SIGNAL = 0x20;
+const int TICKER_SIGNAL = 0x40;
+const int RESPONSE_SIGNAL = 0x80;
+
+Thread * XBeeConsumer;
+Thread * XBeeProducer;
+Ticker timer;
+
+int responseStatus;
+
+/*******************************************************/
+/**********************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 pauseTime;
+int btnPin;
+int accSdaPin;
+int accSclPin;
+int xbeeTxPin;
+int xbeeRxPin;
+int xbeeRstPin;
+
+char key[10];
+
+LocalFileSystem local("local");
+
+void ReadConfig(){
+    FILE * f = fopen("/local/rooter.cfg", "r");
+    fscanf(f,"%s %x", key, &panID);
+    pc.printf("Lecture de la config %s : %04x\r\n", key, panID);
+    fscanf(f,"%s %d", key, &pauseTime);
+    pc.printf("Lecture de la config %s : %d\r\n", key, pauseTime);
+    fscanf(f,"%s %d", key, &btnPin);
+    pc.printf("Lecture de la config %s : %d\r\n", key, btnPin);
+    fscanf(f,"%s %d %d", key, &accSdaPin, &accSclPin);
+    pc.printf("Lecture de la config %s : %d %d\r\n", key, accSdaPin, accSclPin);
+    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);
+    fclose(f);
+}
+
+/*******************************************************/
+/**********************XBEE SEND************************/
+/*******************************************************/
+
+char frameID = 0;
+
+inline char GetFrameID(){
+    ++frameID;
+    if (frameID == 0){
+        frameID = 1;
+    }
+    return frameID;
+}
+
+const char coordinator64bit[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const char coordinator16bit[2] = {0xff, 0xfe};
+
+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]);
+        wait_us(25);
+    }
+}
+
+void XBeeSentTransmitCommand(char * data, int dataLength){
+    char buffer[128];
+    buffer[START_IDX] = START;
+    buffer[LENGTH_MSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) >> 8;
+    buffer[LENGTH_LSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) & 0xff;
+    buffer[API_ID_IDX] = API_ID_TRANSMIT;
+    buffer[FRAME_ID_IDX] = GetFrameID();
+    memcpy(&buffer[TRANSMIT_64BIT_MSB_IDX], coordinator64bit, ADDR_64BIT_SIZE);
+    memcpy(&buffer[TRANSMIT_16BIT_MSB_IDX], coordinator16bit, ADDR_16BIT_SIZE);
+    buffer[TRANSMIT_BROADCAST_IDX] = TRANSMIT_DEFAULT_BROADCAST;
+    buffer[TRANSMIT_OPT_IDX] = TRANSMIT_DEFAULT_OPT;
+    memcpy(&buffer[TRANSMIT_DATA_IDX], data, dataLength);
+    
+    SetCheckSum(buffer);
+    
+    while(true) {
+        XBeeSend(buffer, dataLength + TRANSMIT_MIN_SIZE + FRAME_MIN_SIZE);
+    
+        Thread::signal_wait(RESPONSE_SIGNAL);
+        
+        switch (responseStatus){
+        case TRANSMIT_STATUS_OK:
+            return;
+        default:
+            pc.printf("This Transit error occured : %02x\r\n", responseStatus);
+            break;
+        }
+    }
+}
+
+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 HandleXbeeTransmitStatus(char * cmd){
+    switch(cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]){
+    case TRANSMIT_STATUS_OK:
+        responseStatus = cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX];
+        XBeeProducer->signal_set(RESPONSE_SIGNAL);
+        break;
+    default:
+        pc.printf("Unhandled transmit status received : %02x\r\n", cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]);
+    }
+}
+
+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_JOINED_NETWORK:
+        XBeeProducer->signal_set(JOINED_NETWORK_SIGNAL);
+        break;
+    case MODEM_STATUS_DISASSOCIATED:
+        XBeeProducer->signal_clr(JOINED_NETWORK_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;
+    case API_ID_TRANSMIT_STATUS:
+        HandleXbeeTransmitStatus(cmd);
+        break;
+    default:
+        pc.printf("Unhandle XBee Command received : %02x\r\n", cmd[API_ID_IDX]);
+    }
+}
+
+/*******************************************************/
+/************************INIT***************************/
+/*******************************************************/
+
+bool InitAcc(){
+    char cmd[2];
+    char data[1];
+    // Lecture du registre WHO_AM_I (0x2a)
+    cmd[0] = 0x0d;
+    acc->write(0x1d<<1, cmd, 1, true);
+    acc->read(0x1d<<1, data, 1);
+    if (data[0] != 0x2a){
+        return false;
+    }
+    
+    //Activation de l'accéléromètre
+    cmd[0] = 0x2a; // CTRL_REG1
+    cmd[1] = 0x01; // Active = 1
+    acc->write(0x1d<<1,cmd,2,false);
+    
+    return true;
+}
+
+bool InitXBee(){
+    xbeeRst->write(0);
+    wait(0.4);
+    xbeeRst->write(1);
+    
+    Thread::signal_wait(HARDWARE_RESET_SIGNAL);
+    
+    XBeeSendATID();
+    XBeeSendATWR();
+    XBeeSendATAC();
+    
+    Thread::signal_wait(JOINED_NETWORK_SIGNAL);
+    
+    pc.printf("XBee configured\r\n");
+    
+    return true;
+}
+
+/*******************************************************/
+/************************READ***************************/
+/*******************************************************/
+
+int ReadButton(char* buffer){
+    buffer[0] = 'B';
+    buffer[1] = 'T';
+    buffer[2] = 'N';
+    buffer[3] = (*btn); // 0x01 | 0x00
+    
+    return 4;
+}
+
+int ReadAccelerometer(char* buffer){
+    const char deviceAddr = 0x1d<<1;
+    char temp[1];
+    temp[0] = 0x01; // Adresse de OUT_X_MSB
+    
+    buffer[0] = 'A';
+    buffer[1] = 'C';
+    buffer[2] = 'C';
+    // Lecture des données X, Y et Z
+    acc->write(deviceAddr, temp, 1, true);
+    acc->read(deviceAddr, &buffer[3], 6);
+    
+    SetCheckSum(buffer);
+    
+    //Number of bytes to send
+    return 9;
+}
+
+void ReadDevices(){
+    int count;
+    char buffer[64];
+        
+    for ( int i = 0; i < DEVICE_COUNT; ++i){
+        count = readFunctions[i](buffer);
+        XBeeSentTransmitCommand(buffer, count);
+    }
+}
+
+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(){
+    //Initilisation
+    if (!InitAcc()){
+        pc.printf("Connection problem with the ACC\r\n");
+        return false;
+    }
+    
+    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, pauseTime);
+    
+    while(true){
+        Thread::signal_wait(TICKER_SIGNAL);
+        ReadDevices();
+    }
+}
+
+int main() {
+    // Lecture de la configuration.
+    ReadConfig();
+    
+    //Créer les interfaces de communication des capteurs avec les données de la config.
+    DigitalIn mainBtn(GetPinName(btnPin));
+    I2C mainAcc(GetPinName(accSdaPin), GetPinName(accSclPin));
+    Serial mainXbee(GetPinName(xbeeTxPin), GetPinName(xbeeRxPin));
+    DigitalOut mainXbeeRst(GetPinName(xbeeRstPin));
+    
+    //Rendre les interfaces de communication globaux.
+    btn = &mainBtn;
+    acc = &mainAcc;
+    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);
+}