desloges-libioulle / Mbed 2 deprecated app3_router

Dependencies:   mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
libv2001
Date:
Sun Feb 12 16:06:13 2017 +0000
Commit message:
Hello

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
xbee.h Show annotated file Show diff for this revision Revisions of this file
--- /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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sun Feb 12 16:06:13 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#58563e6cba1e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Feb 12 16:06:13 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/176b8275d35d
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xbee.h	Sun Feb 12 16:06:13 2017 +0000
@@ -0,0 +1,152 @@
+#include "mbed.h"
+
+#ifndef XBEE_H
+#define XBEE_H
+
+#define START 0x7E
+
+#define ADDR_64BIT_SIZE 8
+#define ADDR_16BIT_SIZE 2
+#define AT_CMD_ID_SIZE  2
+
+// Présent dans tous les frames
+#define START_IDX      0
+#define LENGTH_MSB_IDX 1
+#define LENGTH_LSB_IDX 2
+#define API_ID_IDX     3
+#define FRAME_MIN_SIZE 4
+
+// Les API ID supportés2
+#define API_ID_AT_CMD          0x08
+#define API_ID_AT_CMD_QUEUE    0x09
+#define API_ID_TRANSMIT        0x10
+#define API_ID_REMOTE_AT_RQST  0x17
+#define API_ID_AT_CMD_RSP      0x88
+#define API_ID_MODEM_STATUS    0x8A
+#define API_ID_TRANSMIT_STATUS 0x8B
+#define API_ID_RECEIVED_PACKET 0x90
+
+// Présent dans la majorité des frames
+#define FRAME_ID_IDX  4
+
+// Spécifique pour l'AT Command
+#define AT_CMD_ID_IDX 5
+#define AT_PARAM_IDX  7
+#define AT_MIN_SIZE   4
+
+// Spécifique pour l'AT Command Queue
+#define AT_QUEUE_CMD_1_IDX   5
+#define AT_QUEUE_CMD_2_IDX   6
+#define AT_QUEUE_PARAM_IDX   7
+#define AT_QUEUE_MIN_SIZE    4
+
+// Spécifique pour la Transmit Command
+#define TRANSMIT_64BIT_MSB_IDX 5
+#define TRANSMIT_64BIT_LSB_IDX 12
+#define TRANSMIT_16BIT_MSB_IDX 13
+#define TRANSMIT_16BIT_LSB_IDX 14
+#define TRANSMIT_BROADCAST_IDX 15
+#define TRANSMIT_OPT_IDX       16
+#define TRANSMIT_DATA_IDX      17
+#define TRANSMIT_MIN_SIZE      14
+
+// Les options de la Transmit Command
+#define TRANSMIT_DEFAULT_BROADCAST 0x00
+#define TRANSMIT_DEFAULT_OPT       0x00
+
+// Spécifique pour la Remote AT Request Command
+#define REMOTE_AT_RQST_64BIT_MSB_IDX 5
+#define REMOTE_AT_RQST_64BIT_LSB_IDX 12
+#define REMOTE_AT_RQST_16BIT_MSB_IDX 13
+#define REMOTE_AT_RQST_16BIT_LSB_IDX 14
+#define REMOTE_AT_RQST_OPT_IDX       15
+#define REMOTE_AT_RQST_AT_CMD1_IDX   16
+#define REMOTE_AT_RQST_AT_CMD2_IDX   17
+#define REMOTE_AT_RQST_AT_PARAM_IDX  18
+#define REMOTE_AT_RQST_MIN_SIZE      15
+
+// Les options pour la Remote AT Request Command
+#define REMOTE_AT_RQST_DEFAULT_OPT      0x00
+#define REMOTE_AT_RQST_OPT_APPLY_CHANGE 0x02
+
+// Spécifique pour la AT Command Response
+#define AT_CMD_RSP_AT_CMD1_IDX 5
+#define AT_CMD_RSP_AT_CMD2_IDX 6
+#define AT_CMD_RSP_STATUS_IDX  7
+#define AT_CMD_RSP_DATA_IDX    8
+#define AT_CMD_RSP_MIN_SIZE    5
+
+// Les status pour la AT Command Response
+#define AT_CMD_RSP_STATUS_OK            0x00
+#define AT_CMD_RSP_STATUS_ERROR         0x01
+#define AT_CMD_RSP_STATUS_INVALID_CMD   0x02
+#define AT_CMD_RSP_STATUS_INVALID_PARAM 0x03
+#define AT_CMD_RSP_STATUS_TX_FAILURE    0x04
+
+// Spécifique pour la Modem Status Command
+#define MODEM_STATUS_STATUS_IDX         4
+
+// Les status pour la Modem Status Command
+#define MODEM_STATUS_HARDWARE_RST        0x00
+#define MODEM_STATUS_JOINED_NETWORK      0x02
+#define MODEM_STATUS_DISASSOCIATED       0x03
+#define MODEM_STATUS_COORDINATOR_STARTED 0x06
+
+// Spécifique pour la Transit Status Command
+#define TRANSMIT_STATUS_16BIT_MSB_IDX        5
+#define TRANSMIT_STATUS_16BIT_LSB_IDX        6
+#define TRANSMIT_STATUS_RETRY_COUNT_IDX      7
+#define TRANSMIT_STATUS_DELIVERY_STATUS_IDX  8
+#define TRANSMIT_STATUS_DISCOVERY_STATUS_IDX 9
+
+#define TRANSMIT_STATUS_OK 0x00
+
+// Spécifique pour la Received Packet Command
+#define RECEIVED_PACKET_64BIT_MSB_IDX 4
+#define RECEIVED_PACKET_64BIT_LSB_IDX 11
+#define RECEIVED_PACKET_16BIT_MSB_IDX 12
+#define RECEIVED_PACKET_16BIT_LSB_IDX 13
+#define RECEIVED_PACKET_OPT_IDX       14
+#define RECEIVED_PACKET_DATA_IDX      15
+#define RECEIVED_PACKET_MIN_SIZE      12
+
+inline uint16_t GetFrameLength(char * buffer){
+    return (((uint16_t)buffer[LENGTH_MSB_IDX]) << 8) + buffer[LENGTH_LSB_IDX];
+}
+
+bool ValidateCheckSum(char * buffer){
+    uint16_t length = GetFrameLength(buffer);
+    
+    char sum = 0;
+    for (int i = 0; i <= length; ++i){
+        sum += buffer[i + API_ID_IDX];
+    }
+    
+    return sum == 0xff;
+}
+
+inline uint16_t GetAtParamLength(char * buffer){
+    return GetFrameLength(buffer) - AT_MIN_SIZE;
+}
+
+inline uint16_t GetAtQueueParamLength(char * buffer){
+    return GetFrameLength(buffer) - AT_QUEUE_MIN_SIZE;
+}
+
+inline uint16_t GetTransmitDataLength(char * buffer){
+    return GetFrameLength(buffer) - TRANSMIT_MIN_SIZE;
+}
+
+inline uint16_t GetRemoteAtRequestParamLength(char * buffer){
+    return GetFrameLength(buffer) - REMOTE_AT_RQST_MIN_SIZE;
+}
+
+inline uint16_t GetAtResponseParamLength(char * buffer){
+    return GetFrameLength(buffer) - AT_CMD_RSP_MIN_SIZE;
+}
+
+inline uint16_t GetReceivedPacketDataLength(char * buffer){
+    return GetFrameLength(buffer) - RECEIVED_PACKET_MIN_SIZE;
+}
+
+#endif
\ No newline at end of file