From f319857e0d91c69d157886cba11236ceb301aa41 Mon Sep 17 00:00:00 2001 From: vezde Date: Fri, 24 Mar 2023 18:18:43 +0100 Subject: [PATCH] remaniement des drivers xbee et commands --- software/dumber3/Application/XBEE/xbee.c | 625 -------------------- software/dumber3/Application/XBEE/xbee.h | 101 ---- software/dumber3/Application/XBEE/xbee_ll.c | 390 ------------ software/dumber3/Application/XBEE/xbee_ll.h | 37 -- software/dumber3/Application/application.c | 27 +- software/dumber3/Application/commands.c | 166 ++---- software/dumber3/Application/commands.h | 92 +-- software/dumber3/Application/config.h | 1 + software/dumber3/Application/xbee.c | 245 +++++--- software/dumber3/Application/xbee.h | 49 +- 10 files changed, 279 insertions(+), 1454 deletions(-) delete mode 100644 software/dumber3/Application/XBEE/xbee.c delete mode 100644 software/dumber3/Application/XBEE/xbee.h delete mode 100644 software/dumber3/Application/XBEE/xbee_ll.c delete mode 100644 software/dumber3/Application/XBEE/xbee_ll.h diff --git a/software/dumber3/Application/XBEE/xbee.c b/software/dumber3/Application/XBEE/xbee.c deleted file mode 100644 index 2f69333..0000000 --- a/software/dumber3/Application/XBEE/xbee.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * xbee.c - * - * Created on: 4 avr. 2022 - * Author: dimercur - */ - - -#include -#include -#include - -#include "xbee.h" -#include "xbee_ll.h" - -#include "cmsis_os.h" -#include "config.h" - -uint16_t XBEE_panID; -uint8_t XBEE_chanID; -uint64_t XBEE_uid; - -char tx_frame_buffer[18+20]; /* space for a tx frame with 20 bytes of data */ -char rx_frame_buffer[18+0x80]; /* space for a rx frame with 0x80 bytes of data (max possible rx frame length) */ - -#define XBEE_TIMEOUT_FOR_STATUS_FRAME 500 // 500 ms for receiving a TX or AT status frame - -int XBEE_EnterCommandMode_PARANOIA() { - char buffer[5]; - uint8_t index; - int status; - - for (index=0; index < 5; index++) - buffer[index]=0; - - // flush eventual furbish - status=XBEE_LL_ReceiveData(buffer, 1, 50); // 50ms - - /* Enter AT command mode */ - if (XBEE_LL_SendData("+++",strlen("+++")) != XBEE_LL_OK) - return XBEE_CONFIG_ERROR; - - status=XBEE_LL_ReceiveData(buffer, 3, 2000); // 50ms - if ((status!=XBEE_LL_ERROR_RX_TIMEOUT) && (status!=XBEE_LL_OK)) // no timeout - return XBEE_CONFIG_ERROR; - - if ((buffer[1]!='O') && (buffer[1]!='K')) // error setting configuration mode - return XBEE_CONFIG_ERROR; - - // wait for an eventual \r at the end - status=XBEE_LL_ReceiveData(buffer, 1, 50); // 50ms - if ((status!=XBEE_LL_ERROR_RX_TIMEOUT)&& (status!=XBEE_LL_OK)) - return XBEE_CONFIG_ERROR; - - return XBEE_OK; -} - -int XBEE_EnterCommandMode() { - char buffer[5]; - uint8_t index; - int status; - - for (index=0; index < 5; index++) - buffer[index]=0; - - /* Enter AT command mode */ - if (XBEE_LL_SendData("+++",strlen("+++")) != XBEE_LL_OK) - return XBEE_CONFIG_ERROR; - - status=XBEE_LL_ReceiveData(buffer, 3, 2000); // 2s - if (status!=XBEE_LL_OK) // timeout - return XBEE_CONFIG_ERROR; - - if (strstr(buffer, "OK")==NULL) // error setting configuration mode - return XBEE_CONFIG_ERROR; - - return XBEE_OK; -} - -int XBEE_SetATCommand(char* atcmd) { - char buffer[5]; - uint8_t index; - - for (index=0; index < 5; index++) - buffer[index]=0; - - /* Send AT command */ - if (XBEE_LL_SendData(atcmd,strlen(atcmd)) != XBEE_LL_OK) - return XBEE_AT_CMD_ERROR; - - if (XBEE_LL_ReceiveData(buffer, 3, 500) != XBEE_LL_OK) // Timeout: 500 ms - return XBEE_AT_CMD_ERROR; - - if (strcmp(buffer,"OK\r")!=0) // error setting configuration mode - return XBEE_AT_CMD_ERROR; - - return XBEE_OK; -} - -int XBEE_GetATValue(char* atcmd, char* value) { - char tmp; - uint8_t index; - - for (index=0; index < 20; index++) - value[index]=0; - - /* Send AT Cmd */ - if (XBEE_LL_SendData(atcmd,strlen(atcmd)) != XBEE_LL_OK) - return XBEE_AT_CMD_ERROR; - - /* Problem. We don't know the length of received data, only that answer end with \n - * So, we must loop until we have received all data - */ - tmp = 0; - index=0; - - while (tmp!='\r') { - if (XBEE_LL_ReceiveData(&tmp, 1, 500) != XBEE_LL_OK) // timeout 500 ms - return XBEE_AT_CMD_ERROR; - - if (index >=20 ) return XBEE_AT_CMD_ERROR; // too much data received - value[index] = (char)tmp; - index++; - } - - return XBEE_OK; -} - -void XBEE_EncodeTransmissionFrame(char* frame, char* data, uint64_t destination, uint8_t frame_id, uint8_t pan_broadcast) { - int i; - int data_length = strlen(data); - uint8_t checksum; - - frame[0] = '~'; - frame[1] = (char)((uint16_t)(14+data_length)>>8); - frame[2] = (char)((uint16_t)(14+data_length)); - frame[3] = (char)XBEE_TX_REQUEST_TYPE; - frame[4] = (char)frame_id; - - for (i=5; i<5+8; i++) { - frame[i] = (char)(destination >>(64-8)); - destination = destination <<8; - } - - frame[13] = 0xFF; - frame[14] = 0xFE; - frame[15] = 0; - frame[16] = pan_broadcast ? 0x2 : 0x0; - - for (i=0; i>8); - frame[2] = (char)((uint16_t)(4+data_length)); - frame[3] = (char)XBEE_LOCAL_AT_CMD_TYPE; - frame[4] = (char)frame_id; - frame[5] = at_cmd[0]; - frame[6] = at_cmd[1]; - - for (i=0; itype = frame_type; - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->data_length = frame_length-12; - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->options = frame[14]; - - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->source_addr =0; - for (i=0; i<8; i++) { - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->source_addr = ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->source_addr<<8; - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->source_addr +=(uint64_t)frame[4+i]; - } - - for (i=0; i<((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->data_length; i++) { - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->data[i] =(char)frame[15+i]; - } - - ((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->data[((XBEE_RX_PACKET_FRAME*)(*decoded_frame))->data_length]=0x0; // 0 ending frame - - break; - case XBEE_MODEM_STATUS_TYPE: - *decoded_frame = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_MODEM_STATUS_FRAME)); - ((XBEE_MODEM_STATUS_FRAME*)(*decoded_frame))->type = frame_type; - ((XBEE_MODEM_STATUS_FRAME*)(*decoded_frame))->status = frame[4]; - - break; - case XBEE_TX_STATUS_TYPE: - case XBEE_EXTENDED_TX_STATUS_TYPE: - *decoded_frame = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_TX_STATUS_FRAME)); - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->type = frame_type; - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->frame_id = frame[4]; - if (frame_type == XBEE_TX_STATUS_TYPE) { - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->status = frame[5]; - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->retry_count = 0; - } else { - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->status = frame[8]; - ((XBEE_TX_STATUS_FRAME*)(*decoded_frame))->retry_count = frame[7]; - } - - break; - case XBEE_AT_CMD_RESPONSE_TYPE: - *decoded_frame = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_AT_CMD_RESPONSE_FRAME)+(frame_length-5)); - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*decoded_frame))->type = frame_type; - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*decoded_frame))->data_length = frame_length-5; - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*decoded_frame))->status = frame[7]; - - for (i=0; i<((XBEE_AT_CMD_RESPONSE_FRAME*)(*decoded_frame))->data_length; i++) { - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*decoded_frame))->data[i] =(uint8_t)frame[8+i]; - } - break; - default: - *decoded_frame = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_GENERIC_FRAME)); - ((XBEE_GENERIC_FRAME*)(*decoded_frame))->type = frame_type; - return XBEE_INVALID_FRAME; - }; - - return XBEE_OK; -} - -int XBEE_SendFrame (char* frame) { - int frame_length; - - frame_length = (((int)frame[1]<<8))+(int)frame[2]; - frame_length = frame_length + 4; - - if (XBEE_LL_SendData(frame,frame_length) != XBEE_LL_OK) - return XBEE_TX_ERROR; - - return XBEE_OK; -} - -int XBEE_GetFrame (char* frame, int timeout) { - int status; - - status = XBEE_LL_ReceiveData(frame, -1,timeout); - if (status == XBEE_LL_ERROR_RX_TIMEOUT) - return XBEE_RX_TIMEOUT; - else if (status != XBEE_LL_OK) - return XBEE_RX_ERROR; - - return XBEE_OK; -} - -int XBEE_ConfigureDevice(void) { -#define RXBUFFERSIZE 30 - if (XBEE_EnterCommandMode()!=XBEE_OK) - return XBEE_CONFIG_ERROR; - - /* Now configure the device - * 1 - Enable API mode (AP) - * 2 - Change baudrate to 57600 (BD) - * 3 - Get UID of Device (SH+SL) - * 4 - End AT command mode (CN) - */ - - // Set API mode - if (XBEE_SetATCommand("ATAP=1\r")!=XBEE_OK) - return XBEE_CONFIG_ERROR; - - // disable legacy mode for API mode - if (XBEE_SetATCommand("ATAO=0\r")!=XBEE_OK) - return XBEE_CONFIG_ERROR; - - // Set baudrate to 115200 - if (XBEE_SetATCommand("ATBD=7\r")!=XBEE_OK) - return XBEE_CONFIG_ERROR; - - // Finally, exit configuration mode - if (XBEE_SetATCommand("ATCN\r")!=XBEE_OK) - return XBEE_CONFIG_ERROR; - - return XBEE_OK; -} - -int XBEE_Init (void) { - /* First, init GPIO */ - XBEE_LL_ConfigureGPIO(); - - /* then configure timer for timeout */ - //XBEE_LL_ConfigureTimer(); - - /* Then, setup usart at 9600 bauds and configure the device */ - XBEE_LL_ConfigureUart(XBEE_USART, 9600); - if (XBEE_ConfigureDevice() != XBEE_OK) - return XBEE_CONFIG_ERROR; - - /* If it is OK, reconf USART to 115200 bauds */ - XBEE_LL_ConfigureUart(XBEE_USART, 115200); - - /* Wait 100 ms for xbee module to reconf */ - //HAL_Delay(100); - vTaskDelay(msToTicks(100)); - - /* Xbee module is ready to be used */ - return XBEE_OK; -} - -int XBEE_SendData(uint64_t destination, uint8_t frame_id, uint8_t pan_broadcast, char* data, uint8_t *status) { - XBEE_GENERIC_FRAME* tx_status; - - // Format frame for sending data - XBEE_EncodeTransmissionFrame(tx_frame_buffer, data, destination, frame_id, pan_broadcast); - // Send Frame - if (XBEE_SendFrame(tx_frame_buffer) != XBEE_OK) - return XBEE_TX_ERROR; - - // Wait for transmit status - if (XBEE_GetFrame(rx_frame_buffer, XBEE_TIMEOUT_FOR_STATUS_FRAME) != XBEE_OK) //500ms - return XBEE_RX_ERROR; - - // Decode frame - if (XBEE_DecodeFrame(rx_frame_buffer, &tx_status) != XBEE_OK) - return XBEE_INVALID_FRAME; - - if ((tx_status->type != XBEE_TX_STATUS_TYPE) && (tx_status->type != XBEE_EXTENDED_TX_STATUS_TYPE)) { - // Free frame structure - free((void*)tx_status); - - return XBEE_INVALID_FRAME; - } - - *status = ((XBEE_TX_STATUS_FRAME*)tx_status)->status; - - // Free frame structure - free((void*)tx_status); - - return XBEE_OK; -} - -int XBEE_GetData (XBEE_GENERIC_FRAME** frame, int timeout) { - int status; - status = XBEE_LL_ReceiveData(rx_frame_buffer, -1, timeout); - - if (status == XBEE_LL_ERROR_RX_TIMEOUT) - return XBEE_RX_TIMEOUT; - else if (status != XBEE_LL_OK) - return XBEE_RX_ERROR; - - if (XBEE_DecodeFrame(rx_frame_buffer, frame) != XBEE_OK) { - free (*frame); - return XBEE_INVALID_FRAME; - } - - return XBEE_OK; -} - -int XBEE_GetATValueU32(char* at_cmd, uint32_t *value, uint8_t *status) { - XBEE_GENERIC_FRAME* at_status; - int com_status; - - // Format frame for sending data - XBEE_EncodeATFrame(tx_frame_buffer, at_cmd, (uint8_t*)0x0, 0, 1); - - // Send Frame - if (XBEE_SendFrame(tx_frame_buffer) != XBEE_OK) - return XBEE_TX_ERROR; - - // Wait for transmit status - com_status = XBEE_GetFrame(rx_frame_buffer, XBEE_TIMEOUT_FOR_STATUS_FRAME); - if (com_status != XBEE_OK) - return com_status; - - // Decode frame - if (XBEE_DecodeFrame(rx_frame_buffer, &at_status) != XBEE_OK) - return XBEE_INVALID_FRAME; - - if (at_status->type != XBEE_AT_CMD_RESPONSE_TYPE) { - // Free frame structure - free((void*)at_status); - - return XBEE_INVALID_FRAME; - } - - *status = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->status; - - *value = 0; - for (int i=0; i<((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data_length; i++) { - *value = (*value)<<8; - *value += ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data[i]; - } - - // Free frame structure - free((void*)at_status); - - return XBEE_OK; -} - -int XBEE_GetATValueU16(char* at_cmd, uint16_t *value, uint8_t *status) { - XBEE_GENERIC_FRAME* at_status; - int com_status; - - // Format frame for sending data - XBEE_EncodeATFrame(tx_frame_buffer, at_cmd, (uint8_t*)0x0, 0, 1); - - // Send Frame - if (XBEE_SendFrame(tx_frame_buffer) != XBEE_OK) - return XBEE_TX_ERROR; - - // Wait for transmit status - com_status = XBEE_GetFrame(rx_frame_buffer, XBEE_TIMEOUT_FOR_STATUS_FRAME); - if (com_status != XBEE_OK) - return com_status; - - // Decode frame - if (XBEE_DecodeFrame(rx_frame_buffer, &at_status) != XBEE_OK) - return XBEE_INVALID_FRAME; - - if (at_status->type != XBEE_AT_CMD_RESPONSE_TYPE) { - // Free frame structure - free((void*)at_status); - - return XBEE_INVALID_FRAME; - } - - *status = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->status; - - *value = 0; - if (((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data_length ==1) - *value = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data[0]; - else if (((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data_length ==2) { - *value = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data[0]; - *value = (*value)<<8; - *value += ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data[1]; - } - - // Free frame structure - free((void*)at_status); - - return XBEE_OK; -} - -int XBEE_GetATValueU8(char* at_cmd, uint8_t *value, uint8_t *status) { - XBEE_GENERIC_FRAME* at_status; - int com_status; - - // Format frame for sending data - XBEE_EncodeATFrame(tx_frame_buffer, at_cmd, (uint8_t*)0x0, 0, 1); - - // Send Frame - if (XBEE_SendFrame(tx_frame_buffer) != XBEE_OK) - return XBEE_TX_ERROR; - - // Wait for transmit status - com_status = XBEE_GetFrame(rx_frame_buffer, XBEE_TIMEOUT_FOR_STATUS_FRAME); - if (com_status != XBEE_OK) - return com_status; - - // Decode frame - if (XBEE_DecodeFrame(rx_frame_buffer, &at_status) != XBEE_OK) - return XBEE_INVALID_FRAME; - - if (at_status->type != XBEE_AT_CMD_RESPONSE_TYPE) { - // Free frame structure - free((void*)at_status); - - return XBEE_INVALID_FRAME; - } - - *status = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->status; - - *value = 0; - if (((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data_length ==1) - *value = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->data[0]; - else - return XBEE_INVALID_FRAME; - - // Free frame structure - free((void*)at_status); - - return XBEE_OK; -} - -int XBEE_SetATValueU16(char* at_cmd, uint16_t value, uint8_t *status) { - XBEE_GENERIC_FRAME* at_status; - uint8_t data[2]; - int com_status; - - // Format frame for sending data - data[0] = (uint8_t)(value >>8); - data[1] = (uint8_t)(value & 0xFF); - XBEE_EncodeATFrame(tx_frame_buffer, at_cmd, data, 2, 1); - - // Send Frame - if (XBEE_SendFrame(tx_frame_buffer) != XBEE_OK) - return XBEE_TX_ERROR; - - // Wait for transmit status - com_status = XBEE_GetFrame(rx_frame_buffer, XBEE_TIMEOUT_FOR_STATUS_FRAME); - if (com_status != XBEE_OK) - return com_status; - - // Decode frame - if (XBEE_DecodeFrame(rx_frame_buffer, &at_status) != XBEE_OK) - return XBEE_INVALID_FRAME; - - if (at_status->type != XBEE_AT_CMD_RESPONSE_TYPE) { - // Free frame structure - free((void*)at_status); - - return XBEE_INVALID_FRAME; - } - - *status = ((XBEE_AT_CMD_RESPONSE_FRAME*)at_status)->status; - - // Free frame structure - free((void*)at_status); - - return XBEE_OK; -} - -int XBEE_SetChannel(uint8_t channel) { - uint8_t status; - int com_status; - - if ((channel < XBEE_CHANNEL_FIRST) || (channel > XBEE_CHANNEL_LAST)) // Invalid channel value - return XBEE_AT_CMD_ERROR; - - com_status = XBEE_SetATValueU16("CH", (uint16_t)channel, &status); - if (com_status != XBEE_OK) - return com_status; - - if (status != XBEE_AT_STATUS_SUCCESS) - return XBEE_AT_CMD_ERROR; - - return XBEE_OK; -} - -int XBEE_SetPanID(uint16_t panid) { - uint8_t status; - int com_status; - - com_status=XBEE_SetATValueU16("ID", panid, &status); - if (com_status != XBEE_OK) - return com_status; - - if (status != XBEE_AT_STATUS_SUCCESS) - return XBEE_AT_CMD_ERROR; - - return XBEE_OK; -} - -int XBEE_GetRSSI(uint8_t *rssi) { - uint8_t status; - int com_status; - - com_status=XBEE_GetATValueU8("DB", rssi, &status); - if (com_status != XBEE_OK) - return com_status; - - if (status != XBEE_AT_STATUS_SUCCESS) - return XBEE_AT_CMD_ERROR; - - return XBEE_OK; -} - -int XBEE_GetUID(uint64_t *uid) { - uint8_t status; - uint32_t id=0; - int com_status; - - com_status = XBEE_GetATValueU32("SH", &id, &status); - if (com_status != XBEE_OK) - return com_status; - - *uid = ((uint64_t)id<<32); - - com_status = XBEE_GetATValueU32("SL", &id, &status); - if (com_status != XBEE_OK) - return com_status; - - *uid += id; - - if (status != XBEE_AT_STATUS_SUCCESS) - return XBEE_AT_CMD_ERROR; - - return XBEE_OK; -} - diff --git a/software/dumber3/Application/XBEE/xbee.h b/software/dumber3/Application/XBEE/xbee.h deleted file mode 100644 index c06b5be..0000000 --- a/software/dumber3/Application/XBEE/xbee.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * xbee.h - * - * Created on: 4 avr. 2022 - * Author: dimercur - */ - -#ifndef BSP_XBEE_XBEE_H_ -#define BSP_XBEE_XBEE_H_ - -#include "stm32l4xx_hal.h" - -#define XBEE_OK 0 -#define XBEE_CONFIG_ERROR 2 -#define XBEE_AT_CMD_ERROR 3 -#define XBEE_RX_TIMEOUT 4 -#define XBEE_RX_ERROR 5 -#define XBEE_TX_ERROR 6 -#define XBEE_INVALID_FRAME 7 - -#define XBEE_RX_PACKET_TYPE 0x90 -#define XBEE_RX_EXPLICIT_TYPE 0x91 -#define XBEE_TX_STATUS_TYPE 0x89 -#define XBEE_AT_CMD_RESPONSE_TYPE 0x88 -#define XBEE_MODEM_STATUS_TYPE 0x8A -#define XBEE_EXTENDED_TX_STATUS_TYPE 0x8B -#define XBEE_LOCAL_AT_CMD_TYPE 0x08 -#define XBEE_TX_REQUEST_TYPE 0x10 -#define XBEE_TX_EXPLICIT_TYPE 0x11 - -#define XBEE_AT_STATUS_SUCCESS 0 -#define XBEE_AT_STATUS_ERROR 1 -#define XBEE_AT_STATUS_INVALID_COMMAND 2 -#define XBEE_AT_STATUS_INVALID_PARAMETER 3 - -#define XBEE_TX_STATUS_SUCCESS 0x00 -#define XBEE_TX_STATUS_NO_ACK 0x01 -#define XBEE_TX_STATUS_CCA_FAILURE 0x02 -#define XBEE_TX_STATUS_NETWORK_NO_ACK 0x21 - -#define XBEE_MODEM_STATUS_HW_RST 0x00 -#define XBEE_MODEM_STATUS_JOINED 0x02 - -#define XBEE_RX_OPTIONS_ACKNOWLEDGED 0x01 -#define XBEE_RX_OPTIONS_BRODCASTED 0x02 -#define XBEE_RX_OPTIONS_PAN_BROADCASTED 0x04 - -#define XBEE_CHANNEL_FIRST 0x0B -#define XBEE_CHANNEL_LAST 0x1A - -#define XBEE_BROADCAST_ADDRESS 0x000000000000FFFF - -#define XBEE_PANID_BROADCAST SET -#define XBEE_NO_PANID_BROADCAST RESET - -typedef struct { - uint8_t type; -} XBEE_GENERIC_FRAME; - -typedef struct { - uint8_t type; - uint64_t source_addr; - uint8_t options; - uint8_t data_length; - char data[]; -} XBEE_RX_PACKET_FRAME; - -typedef struct { - uint8_t type; - uint8_t frame_id; - uint16_t at_cmd; - uint8_t status; - uint8_t data_length; - char data[]; -} XBEE_AT_CMD_RESPONSE_FRAME; - -typedef struct { - uint8_t type; - uint8_t frame_id; - uint8_t status; - uint8_t retry_count; -} XBEE_TX_STATUS_FRAME; - -typedef struct { - uint8_t type; - uint8_t status; -} XBEE_MODEM_STATUS_FRAME; - -int XBEE_ConfigureDevice(void); -int XBEE_Init (void); - -int XBEE_DecodeFrame(char* frame, XBEE_GENERIC_FRAME** decoded_frame); -int XBEE_GetData (XBEE_GENERIC_FRAME** frame, int timeout); // timeout in ms -int XBEE_SendData(uint64_t destination, uint8_t frame_id, uint8_t pan_broadcast, char* data, uint8_t *status); - -int XBEE_SetChannel(uint8_t channel); -int XBEE_SetPanID(uint16_t panid); -int XBEE_GetRSSI(uint8_t *rssi); -int XBEE_GetUID(uint64_t *uid); - -#endif /* BSP_XBEE_XBEE_H_ */ diff --git a/software/dumber3/Application/XBEE/xbee_ll.c b/software/dumber3/Application/XBEE/xbee_ll.c deleted file mode 100644 index c236b9e..0000000 --- a/software/dumber3/Application/XBEE/xbee_ll.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * xbee_ll.c - * - * Created on: Apr 6, 2022 - * Author: dimercur - */ - -#include "xbee_ll.h" -#include "stm32l4xx_hal.h" - -#include "cmsis_os.h" -#include "config.h" - -UART_HandleTypeDef XBEE_LL_Uart; -//LPTIM_HandleTypeDef XBEE_LL_Timer; -char* XBEE_LL_RxBuffer; -static TaskHandle_t xbee_ll_rx_thread_handler; -static TaskHandle_t xbee_ll_tx_thread_handler; - -typedef enum { - XBEE_LL_MODE_TRANSPARENT=0, - XBEE_LL_MODE_API -} XBEE_LL_ModeType; - -XBEE_LL_ModeType XBEE_LL_Mode; -FlagStatus XBEE_LL_RxReady; -FlagStatus XBEE_LL_TxReady; - -typedef enum -{ - XBEE_LL_RX_STATE_OK=0, - XBEE_LL_RX_STATE_WAIT_DATA, - XBEE_LL_RX_STATE_WAIT_HEADER, - XBEE_LL_RX_STATE_WAIT_EOF, - XBEE_LL_RX_STATE_TIMEOUT, - XBEE_LL_RX_STATE_ERROR, -} XBEE_LL_RxStatus; -XBEE_LL_RxStatus XBEE_LL_RXState; - -typedef struct { - uint8_t startChar; - uint16_t frameLength; -} API_LENGTH_ST; - -volatile uint16_t tmp; // to be used by XBEE_LL_ConfigureUart -void XBEE_LL_StartTimeout(uint32_t timeout); -void XBEE_LL_StopTimeout(void); - -int XBEE_LL_ConfigureUart(USART_TypeDef* usart, uint32_t baudrate) { - __HAL_RCC_USART1_FORCE_RESET(); - __HAL_RCC_USART1_RELEASE_RESET(); - - XBEE_LL_Uart.Instance = usart; - XBEE_LL_Uart.Init.BaudRate = baudrate; - XBEE_LL_Uart.Init.WordLength = UART_WORDLENGTH_8B; - XBEE_LL_Uart.Init.StopBits = UART_STOPBITS_1; - XBEE_LL_Uart.Init.Parity = UART_PARITY_NONE; - XBEE_LL_Uart.Init.Mode = UART_MODE_TX_RX; - XBEE_LL_Uart.Init.HwFlowCtl = UART_HWCONTROL_NONE; - XBEE_LL_Uart.Init.OverSampling = UART_OVERSAMPLING_16; - XBEE_LL_Uart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; - XBEE_LL_Uart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; - - if (HAL_UART_Init(&XBEE_LL_Uart) != HAL_OK) - { - return XBEE_LL_ERROR_USART_CFG; - } - - /* Debug usart */ - tmp = usart->CR1; - tmp = usart->CR2; - tmp = usart->CR3; - tmp = usart->BRR; - tmp = usart->ICR; - tmp = usart->ISR; - tmp = usart->GTPR; - tmp = usart->RDR; - tmp = usart->TDR; - - XBEE_LL_TxReady = SET; - XBEE_LL_RxReady = SET; - - return XBEE_LL_OK; -} - -void XBEE_LL_ConfigureGPIO(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - - /**USART1 GPIO Configuration - PA8 ------> XBEE_RESET - PA11 ------> XBEE_SLEEP_RQ - PB3 -------> XBEE_SLEEP - */ - GPIO_InitStruct.Pin = XBEE_RST_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(XBEE_RST_PORT, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = XBEE_SLEEP_RQ_PIN; - HAL_GPIO_Init(XBEE_SLEEP_RQ_PORT, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = XBEE_SLEEP_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(XBEE_SLEEP_PORT, &GPIO_InitStruct); - - /* Set SLEEP_REQ pin to 0 (disable sleep mode) - * - */ - HAL_GPIO_WritePin(XBEE_SLEEP_RQ_PORT, XBEE_SLEEP_RQ_PIN, GPIO_PIN_RESET); - //HAL_Delay(300); - vTaskDelay(msToTicks(300)); - /* Reset XBEE module - * Pin to 0 -> wait 100 ms -> pin to 1 -> wait 300 ms - */ - HAL_GPIO_WritePin(XBEE_RST_PORT, XBEE_RST_PIN, GPIO_PIN_RESET); - //HAL_Delay(50); - vTaskDelay(msToTicks(100)); - - HAL_GPIO_WritePin(XBEE_RST_PORT, XBEE_RST_PIN, GPIO_PIN_SET); - //HAL_Delay(400); - vTaskDelay(msToTicks(400)); -} - -//void XBEE_LL_ConfigureTimer(void) { -// /* Peripheral reset */ -// __HAL_RCC_LPTIM1_FORCE_RESET(); -// __HAL_RCC_LPTIM1_RELEASE_RESET(); -// -// XBEE_LL_Timer.Instance = LPTIM1; -// XBEE_LL_Timer.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; -// XBEE_LL_Timer.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV128; -// XBEE_LL_Timer.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; -// XBEE_LL_Timer.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; -// XBEE_LL_Timer.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; -// XBEE_LL_Timer.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; -// XBEE_LL_Timer.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO; -// XBEE_LL_Timer.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO; -// -// HAL_LPTIM_Init(&XBEE_LL_Timer); -// __HAL_LPTIM_ENABLE(&XBEE_LL_Timer); -// __HAL_LPTIM_ENABLE_IT(&XBEE_LL_Timer, LPTIM_IT_CMPM); -// __HAL_LPTIM_AUTORELOAD_SET(&XBEE_LL_Timer, 0xFFFF); /* full scale for timer */ -// __HAL_LPTIM_DISABLE(&XBEE_LL_Timer); -//} - -/** - * @brief Start the Counter mode in interrupt mode. - * @param hlptim LPTIM handle - * @param Period Specifies the Autoreload value. - * This parameter must be a value between 0x0000 and 0xFFFF. - * @retval HAL status - */ -//void XBEE_LL_StartTimeout(uint32_t timeout) -//{ -// uint16_t compare_val; -// uint16_t period; -// -// if (timeout>0) { -// /* Enable the Peripheral */ -// __HAL_LPTIM_ENABLE(&XBEE_LL_Timer); -// -// /* Clear Compare match flag */ -// __HAL_LPTIM_CLEAR_FLAG(&XBEE_LL_Timer,LPTIM_IT_CMPM); -// /* Load the period value + current counter in the compare register */ -// period = (uint16_t)((timeout*(4000000UL/128UL))/1000UL); -// -// if (XBEE_LL_Timer.Instance->CNT>period) -// compare_val = (uint16_t)(((uint32_t)XBEE_LL_Timer.Instance->CNT)+period-65536); -// else -// compare_val = (uint16_t)(((uint32_t)XBEE_LL_Timer.Instance->CNT)+period); -// __HAL_LPTIM_COMPARE_SET(&XBEE_LL_Timer, compare_val); -// -// /* Start timer in continuous mode */ -// __HAL_LPTIM_START_CONTINUOUS(&XBEE_LL_Timer); -// } -//} - -/** - * @brief Stop the Counter mode in interrupt mode. - * @param hlptim LPTIM handle - * @retval HAL status - */ -//void XBEE_LL_StopTimeout(void) -//{ -// /* Disable the Peripheral */ -// __HAL_LPTIM_DISABLE(&XBEE_LL_Timer); -// -// /* Clear Compare match flag */ -// __HAL_LPTIM_CLEAR_FLAG(&XBEE_LL_Timer,LPTIM_IT_CMPM); -//} - -int XBEE_LL_SendData(char* data, int length) { - int data_length; - - xbee_ll_tx_thread_handler = xTaskGetCurrentTaskHandle(); - - if (length == -1) { - /* Envoi d'un trame API, donc, recherche de la longueur dans la trame */ - data_length = ((API_LENGTH_ST*)data)->frameLength + 3 +1; //+3 for header and + 1 for checksum - } - else data_length = length; - - //while (XBEE_LL_TxReady != SET); // wait for last transfert to end - ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS(100)); // wait max 100 ms - - /* Restore huart->gState to ready */ - //XBEE_LL_Uart.gState = HAL_UART_STATE_READY; - XBEE_LL_TxReady = RESET; - if(HAL_UART_Transmit_DMA(&XBEE_LL_Uart, (uint8_t*)data, data_length)!= HAL_OK) { - XBEE_LL_TxReady = SET; - return XBEE_LL_ERROR_TX; - } - - xbee_ll_tx_thread_handler = NULL; - return XBEE_LL_OK; -} - -int XBEE_LL_ReceiveData(char* data, int length, int timeout) { - uint32_t ulNotificationValue; - int data_length; - - xbee_ll_rx_thread_handler = xTaskGetCurrentTaskHandle(); - while (XBEE_LL_RxReady != SET); // wait for last RX to end - - if (length == -1) { - // set API mode - XBEE_LL_Mode = XBEE_LL_MODE_API; - data_length = 3; // 3 bytes for api header (start char and length) - XBEE_LL_RxBuffer = data; - XBEE_LL_RXState = XBEE_LL_RX_STATE_WAIT_HEADER; - } else { - // set TRANSPARENT mode - XBEE_LL_Mode = XBEE_LL_MODE_TRANSPARENT; - XBEE_LL_RXState = XBEE_LL_RX_STATE_WAIT_DATA; - data_length = length; - } - - //XBEE_LL_StartTimeout(timeout); - - XBEE_LL_RxReady = RESET; - - if(HAL_UART_Receive_DMA(&XBEE_LL_Uart, (uint8_t*)data, data_length)!= HAL_OK) { - //XBEE_LL_StopTimeout(); - HAL_UART_DMAStop(&XBEE_LL_Uart); - XBEE_LL_RXState = XBEE_LL_RX_STATE_ERROR; - XBEE_LL_RxReady = SET; - - return XBEE_LL_ERROR_RX; - } - - //while (XBEE_LL_RxReady != SET); // wait for RX to end - if (timeout == 0) - ulNotificationValue = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS(portMAX_DELAY)); // wait max 100 ms - else - ulNotificationValue = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS(timeout)); // wait max 100 ms - - //XBEE_LL_StopTimeout(); - - if (ulNotificationValue != 1) { - /* The reception timed out. */ - HAL_UART_DMAStop(&XBEE_LL_Uart); - XBEE_LL_RXState = XBEE_LL_RX_STATE_TIMEOUT; - XBEE_LL_RxReady = SET; - } - - xbee_ll_rx_thread_handler = NULL; - - if (XBEE_LL_RXState == XBEE_LL_RX_STATE_ERROR) - return XBEE_LL_ERROR_RX; - else if (XBEE_LL_RXState == XBEE_LL_RX_STATE_TIMEOUT) { - HAL_UART_DMAStop(&XBEE_LL_Uart); - return XBEE_LL_ERROR_RX_TIMEOUT; - } - else - return XBEE_LL_OK; -} - -/** - * @brief Rx Transfer completed callback - * @param UartHandle: UART handle - * @note This example shows a simple way to report end of DMA Rx transfer, and - * you can add your own implementation. - * @retval None - */ -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - int frame_length; - - if (XBEE_LL_Mode == XBEE_LL_MODE_TRANSPARENT){ - /* Set reception flag: transfer complete*/ - XBEE_LL_RXState = XBEE_LL_RX_STATE_OK; - XBEE_LL_RxReady = SET; - - if (xbee_ll_rx_thread_handler != NULL) { - /* Notify the task that an event has been emitted. */ - vTaskNotifyGiveFromISR(xbee_ll_rx_thread_handler, &xHigherPriorityTaskWoken ); - - /* There are no more eventin progress, so no tasks to notify. */ - xbee_ll_rx_thread_handler = NULL; - - /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch - should be performed to ensure the interrupt returns directly to the highest - priority task. The macro used for this purpose is dependent on the port in - use and may be called portEND_SWITCHING_ISR(). */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - } - } else { - if (XBEE_LL_RXState == XBEE_LL_RX_STATE_WAIT_EOF) { - /* Set reception flag: transfer complete*/ - XBEE_LL_RXState = XBEE_LL_RX_STATE_OK; - XBEE_LL_RxReady = SET; - - if (xbee_ll_rx_thread_handler != NULL) { - /* Notify the task that an event has been emitted. */ - vTaskNotifyGiveFromISR(xbee_ll_rx_thread_handler, &xHigherPriorityTaskWoken ); - - /* There are no more eventin progress, so no tasks to notify. */ - xbee_ll_rx_thread_handler = NULL; - - /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch - should be performed to ensure the interrupt returns directly to the highest - priority task. The macro used for this purpose is dependent on the port in - use and may be called portEND_SWITCHING_ISR(). */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - } - } else { - frame_length = 1+(((int)XBEE_LL_RxBuffer[1]<<8))+(int)XBEE_LL_RxBuffer[2]; - XBEE_LL_RXState = XBEE_LL_RX_STATE_WAIT_EOF; - - if(HAL_UART_Receive_DMA(&XBEE_LL_Uart, (uint8_t*)(XBEE_LL_RxBuffer+3), frame_length)!= HAL_OK) { - // Something went wrong - //XBEE_LL_StopTimeout(); - XBEE_LL_RXState = XBEE_LL_RX_STATE_ERROR; - XBEE_LL_RxReady = SET; - } - } - } -} - -/** - * @brief Tx Transfer completed callback - * @param UartHandle: UART handle - * @note This example shows a simple way to report end of DMA Rx transfer, and - * you can add your own implementation. - * @retval None - */ -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* Set transmission flag: transfer complete*/ - XBEE_LL_TxReady = SET; - - /* Restore huart->gState to ready */ - //UartHandle->gState = HAL_UART_STATE_READY; - - if (xbee_ll_tx_thread_handler != NULL) { - /* Notify the task that an event has been emitted. */ - vTaskNotifyGiveFromISR(xbee_ll_tx_thread_handler, &xHigherPriorityTaskWoken ); - - /* There are no more eventin progress, so no tasks to notify. */ - xbee_ll_tx_thread_handler = NULL; - - /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch - should be performed to ensure the interrupt returns directly to the highest - priority task. The macro used for this purpose is dependent on the port in - use and may be called portEND_SWITCHING_ISR(). */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - } -} - -/** - * @brief This function handles LPTIM1 global interrupt. - */ -//void LPTIM1_IRQHandler(void) -//{ -// /* Clear Compare match flag */ -// __HAL_LPTIM_CLEAR_FLAG(&XBEE_LL_Timer,LPTIM_IT_CMPM); -// -// XBEE_LL_StopTimeout(); -// -// /* Set reception flag: Timeout*/ -// XBEE_LL_RXState = XBEE_LL_RX_STATE_TIMEOUT; -// XBEE_LL_RxReady = SET; -//} - diff --git a/software/dumber3/Application/XBEE/xbee_ll.h b/software/dumber3/Application/XBEE/xbee_ll.h deleted file mode 100644 index 179e0b1..0000000 --- a/software/dumber3/Application/XBEE/xbee_ll.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * xbee_ll.h - * - * Created on: Apr 6, 2022 - * Author: dimercur - */ - -#ifndef BSP_XBEE_XBEE_LL_H_ -#define BSP_XBEE_XBEE_LL_H_ - -#include "stm32l4xx_hal.h" - -typedef void (*RXCallback)(char* data, int length); - -#define XBEE_USART USART1 -#define XBEE_RST_PIN GPIO_PIN_8 -#define XBEE_RST_PORT GPIOA - -#define XBEE_SLEEP_RQ_PIN GPIO_PIN_11 -#define XBEE_SLEEP_RQ_PORT GPIOA - -#define XBEE_SLEEP_PIN GPIO_PIN_3 -#define XBEE_SLEEP_PORT GPIOB - -#define XBEE_LL_OK 0 -#define XBEE_LL_ERROR_USART_CFG 1 -#define XBEE_LL_ERROR_TX 2 -#define XBEE_LL_ERROR_RX 3 -#define XBEE_LL_ERROR_RX_TIMEOUT 4 - -int XBEE_LL_ConfigureUart(USART_TypeDef* usart, uint32_t baudrate); -void XBEE_LL_ConfigureGPIO(void); -void XBEE_LL_ConfigureTimer(void); -int XBEE_LL_SendData(char* data, int length) ; -int XBEE_LL_ReceiveData(char* data, int length, int timeout); - -#endif /* BSP_XBEE_XBEE_LL_H_ */ diff --git a/software/dumber3/Application/application.c b/software/dumber3/Application/application.c index e51cb77..5a8bdc9 100644 --- a/software/dumber3/Application/application.c +++ b/software/dumber3/Application/application.c @@ -63,21 +63,23 @@ typedef struct { char powerOffRequired; } APPLICATION_Infos; - APPLICATION_Infos systemInfos = {0}; +APPLICATION_Infos systemInfos = {0}; void APPLICATION_Init(void) { /* Init des messages box */ - MESSAGE_Init(); + MESSAGE_Init(); - LEDS_Init(); - //LEDS_Tests(); + /* Init de l'afficheur */ + LEDS_Init(); + //LEDS_Tests(); - //XBEE_Init(); - //BATTERIE_Init(); - //MOTEURS_Init(); - //SEQUENCEUR_Init(); + /* Init de la partie RF / reception des messages */ + XBEE_Init(); + //BATTERIE_Init(); + //MOTEURS_Init(); + //SEQUENCEUR_Init(); - /*MOTEURS_Init(); + /*MOTEURS_Init(); MOTEURS_Test();*/ /* Create the task without using any dynamic memory allocation. */ @@ -91,8 +93,7 @@ void APPLICATION_Init(void) { &xTaskApplicationMain); /* Variable to hold the task's data structure. */ vTaskResume(xHandleApplicationMain); - /* Create the task without using any dynamic memory allocation. */ - + /* Create a periodic task without using any dynamic memory allocation. */ xHandleTimerTimeout = xTimerCreateStatic( "Seq Timer", //pdMS_TO_TICKS(100), @@ -103,8 +104,8 @@ void APPLICATION_Init(void) { &xBufferTimerTimeout); xTimerStart(xHandleTimerTimeout,0 ); - APPLICATION_CntTimeout =0; - APPLICATION_CntPowerOff=0; + APPLICATION_CntTimeout =0; + APPLICATION_CntPowerOff=0; } void APPLICATION_MainThread(void* params) { diff --git a/software/dumber3/Application/commands.c b/software/dumber3/Application/commands.c index 2038bdb..15d2681 100644 --- a/software/dumber3/Application/commands.c +++ b/software/dumber3/Application/commands.c @@ -12,139 +12,81 @@ /* Definition des commandes */ -//void cmdAddChecksum(char* ans) { -// uint16_t j; -// unsigned char checksum=0; -// -// for (j = 0; ans[j] != END_OF_CMD; j++) -// checksum ^= ans[j]; -// if (checksum == END_OF_CMD) -// checksum++; -// ans[j] = checksum; -// ans[j + 1] = END_OF_CMD; -//} - -/** - * @brief Verifie le checksum de la commande recue - * - * Vérifie le dernier carctére de receiptString sensé être le checksum. - * Si celui-ci est bon, ll retournera 0 et supprimera le checksum du tableau receiptString - * sinon il retournera 1 sans faire de modification. - * @param None - * @retval 0 ou 1 - * - */ -ANS_Type cmdVerifyChecksum(char* cmd) { - uint16_t j; - uint16_t length; - unsigned char checksum=0; - - length = strlen(cmd); - for (j = 0; j < length - 2; j++) { - checksum ^= cmd[j]; - } - if (checksum == END_OF_CMD) - checksum++; - - if (cmd[j] == checksum) { - cmd[length - 2] = 0; - cmd[length - 1] = 0; - cmd[length] = 0; - - return okANS; - } else - return errANS; -} - -ANS_Type cmdIsValid(char* cmd) { - uint16_t j; - uint16_t length; - unsigned char checksum=0; - - length = strlen(cmd); - for (j = 0; j < length - 2; j++) { - checksum ^= cmd[j]; - } - if (checksum == END_OF_CMD) - checksum++; - - if (cmd[j] == checksum) - return okANS; - else - return errANS; -} - CMD_Generic* cmdDecode(char* cmd) { CMD_Generic* decodedCmd; - if (cmdVerifyChecksum(cmd) != okANS) - return CMD_DECODE_INVALID; - else if (cmd[0] == moveCMD) { - int32_t laps; - uint16_t testReception = sscanf(cmd, "M=%li", &laps); + switch (cmd[0]) + { + case CMD_MOVE: + decodedCmd = (CMD_Generic*)malloc(sizeof(CMD_Move)); + ((CMD_Move*)decodedCmd)->distance = ((uint16_t)cmd[1]<<8) + (uint16_t)cmd[2]; + break; - if (testReception!=1) return CMD_DECODE_INVALID; - else { - decodedCmd=(CMD_Generic*)malloc(sizeof(CMD_Move)); - ((CMD_Move*)decodedCmd)->type = moveCMD; - ((CMD_Move*)decodedCmd)->distance = laps; - } - } else if (cmd[0] == turnCMD) { - int32_t degree; - uint16_t testReception = sscanf(cmd, "T=%li", °ree); + case CMD_TURN: + decodedCmd = (CMD_Generic*)malloc(sizeof(CMD_Turn)); - if (testReception != 1) return CMD_DECODE_INVALID; - else { - degree = degree * 1.40; - decodedCmd=(CMD_Generic*)malloc(sizeof(CMD_Turn)); - ((CMD_Turn*)decodedCmd)->type = moveCMD; - ((CMD_Turn*)decodedCmd)->turns= degree; - } - } else if (cmd[0] == setMotorCMD) { - int32_t moteurG,moteurD; - uint16_t testReception = sscanf(cmd, "m=%li,%li", &moteurG, &moteurD); + ((CMD_Turn*)decodedCmd)->turns = ((uint16_t)cmd[1]<<8) + (uint16_t)cmd[2]; + ((CMD_Turn*)decodedCmd)->turns = ((CMD_Turn*)decodedCmd)->turns * 1.4; - if (testReception != 1) return CMD_DECODE_INVALID; - else { - decodedCmd=(CMD_Generic*)malloc(sizeof(CMD_SetMotor)); - ((CMD_SetMotor*)decodedCmd)->type = moveCMD; - ((CMD_SetMotor*)decodedCmd)->motor_left= moteurG; - ((CMD_SetMotor*)decodedCmd)->motor_right= moteurD; - } - } else if ((cmd[0] == pingCMD) || (cmd[0] == resetCMD) || (cmd[0] == startWWatchDogCMD) || (cmd[0] == resetWatchdogCMD) || - (cmd[0] == getBatteryVoltageCMD) || (cmd[0] == getVersionCMD) || (cmd[0] == startWithoutWatchCMD) || (cmd[0] == busyStateCMD) || - (cmd[0] == testCMD) || (cmd[0] == debugCMD) || (cmd[0] == powerOffCMD)) { - decodedCmd=(CMD_Generic*)malloc(sizeof(CMD_Generic)); + break; + + case CMD_PING: + case CMD_RESET: + case CMD_START_WITHOUT_WATCHDOG: + case CMD_START_WITH_WATCHDOG: + case CMD_RESET_WATCHDOG: + case CMD_GET_BATTERY: + case CMD_GET_BUSY_STATE: + case CMD_GET_VERSION: + case CMD_TEST: + case CMD_DEBUG: + case CMD_POWER_OFF: + decodedCmd = (CMD_Generic*)malloc(sizeof(CMD_Generic)); decodedCmd->type = cmd[0]; - } else return CMD_DECODE_UNKNOWN; + + default: + decodedCmd = CMD_DECODE_UNKNOWN; + } return decodedCmd; } -void cmdSendAnswer(ANS_Type ans) { - char cmdStr[4]; - cmdStr[0] = (char)ans; - cmdStr[1] = (char)ans; - cmdStr[2] = END_OF_CMD; - cmdStr[3] = 0; // end of string - XBEE_SendData(cmdStr, 3); +void cmdSendAnswer(uint8_t ans) { + ANS_Generic answer; + + answer.ans = ans; + XBEE_SendData((char*)&answer, sizeof (answer)); } void cmdSendBatteryLevel(char level) { - char cmdStr[4]; + ANS_Battery answer; char localLevel=level; if (localLevel<0) localLevel=0; else if (localLevel>2) localLevel=2; - cmdStr[0] = localLevel+'0'; - cmdStr[1] = localLevel+'0'; - cmdStr[2] = END_OF_CMD; - cmdStr[3] = 0; // end of string - XBEE_SendData(cmdStr, 3); + answer.ans = ANS_OK; + answer.bat_level = localLevel; + + XBEE_SendData((char*)&answer, sizeof (answer)); } void cmdSendVersion() { - XBEE_SendData(SYSTEM_VERSION_STR, strlen(SYSTEM_VERSION_STR)); + ANS_Version answer; + + answer.ans = ANS_OK; + answer.version = SYSTEM_VERSION; + + XBEE_SendData((char*)&answer, sizeof (answer)); } +void cmdBusyState(uint8_t state) { + ANS_Busy_State answer; + + answer.ans = ANS_OK; + answer.state = state; + + if (answer.state >1) answer.state=0; + + XBEE_SendData((char*)&answer, sizeof (answer)); +} diff --git a/software/dumber3/Application/commands.h b/software/dumber3/Application/commands.h index cb037ba..63d8d1d 100644 --- a/software/dumber3/Application/commands.h +++ b/software/dumber3/Application/commands.h @@ -10,61 +10,71 @@ #include "application.h" -typedef enum { - pingCMD = 'p', - resetCMD = 'r', - setMotorCMD = 'm', - startWWatchDogCMD = 'W', - resetWatchdogCMD = 'w', - getBatteryVoltageCMD = 'v', - getVersionCMD = 'V', - startWithoutWatchCMD = 'u', - moveCMD = 'M', - turnCMD = 'T', - busyStateCMD = 'b', - testCMD = 't', - debugCMD = 'a', - powerOffCMD = 'z' -} CMD_Type; +#define CMD_PING 0x1 +#define CMD_RESET 0x2 +#define CMD_START_WITH_WATCHDOG 0x3 +#define CMD_RESET_WATCHDOG 0x4 +#define CMD_GET_BATTERY 0x5 +#define CMD_GET_VERSION 0x6 +#define CMD_START_WITHOUT_WATCHDOG 0x7 +#define CMD_MOVE 0x8 +#define CMD_TURN 0x9 +#define CMD_GET_BUSY_STATE 0xA +#define CMD_TEST 0xB +#define CMD_DEBUG 0xC +#define CMD_POWER_OFF 0xD -typedef enum { - okANS = 'O', - errANS = 'E', - unknownANS = 'C', - batOK = '2', - batLOW = '1', - batEMPTY = '0' -} ANS_Type; +#define ANS_OK 0x80 +#define ANS_ERR 0x81 +#define ANS_UNKNOWN 0x82 -#define END_OF_CMD '\r' +#define ANS_BAT_OK 0x2 +#define ANS_BAT_LOW 0x1 +#define ANS_BAT_EMPTY 0x0 -typedef struct { - CMD_Type type; +#define ANS_STATE_NOT_BUSY 0x0 +#define ANS_STATE_BUSY 0x1 + +typedef struct __attribute__((packed)) { + uint8_t type; } CMD_Generic; -typedef struct { - CMD_Type type; - int32_t motor_left; - int32_t motor_right; -} CMD_SetMotor; - -typedef struct { - CMD_Type type; - int32_t distance; +typedef struct __attribute__((packed)) { + uint8_t type; + int16_t distance; } CMD_Move; -typedef struct { - CMD_Type type; - int32_t turns; +typedef struct __attribute__((packed)) { + uint8_t type; + int16_t turns; } CMD_Turn; +typedef struct __attribute__((packed)) { + uint8_t ans; +} ANS_Generic; + +typedef struct __attribute__((packed)) { + uint8_t ans; + uint8_t version; +} ANS_Version; + +typedef struct __attribute__((packed)) { + uint8_t ans; + uint8_t bat_level; +} ANS_Battery; + +typedef struct __attribute__((packed)) { + uint8_t ans; + uint8_t state; +} ANS_Busy_State; + #define CMD_DECODE_INVALID ((CMD_Generic*)NULL) #define CMD_DECODE_UNKNOWN ((CMD_Generic*)UINT32_MAX) -ANS_Type cmdIsValid(char* cmd); CMD_Generic* cmdDecode(char* cmd); -void cmdSendAnswer(ANS_Type ans); +void cmdSendAnswer(uint8_t ans); void cmdSendBatteryLevel(char level); void cmdSendVersion(); +void cmdBusyState(uint8_t state); #endif /* INC_CMD_H_ */ diff --git a/software/dumber3/Application/config.h b/software/dumber3/Application/config.h index 721fe1f..0b90a21 100644 --- a/software/dumber3/Application/config.h +++ b/software/dumber3/Application/config.h @@ -8,6 +8,7 @@ #include "cmsis_os.h" #define SYSTEM_VERSION_STR "version 2.0\r" +#define SYSTEM_VERSION 0x20 #define STACK_SIZE 0x100 diff --git a/software/dumber3/Application/xbee.c b/software/dumber3/Application/xbee.c index a4b66d8..110cbfc 100644 --- a/software/dumber3/Application/xbee.c +++ b/software/dumber3/Application/xbee.c @@ -34,7 +34,11 @@ SemaphoreHandle_t xHandleSemaphoreRX = NULL; StaticSemaphore_t xSemaphoreRx; uint8_t* rxBuffer; -uint32_t rxBufferIndex; +uint8_t rxWaitForACK; +uint8_t rxPhase; + +#define XBEE_RX_PHASE_HEADER 1 +#define XBEE_RX_PHASE_BODY 2 /****** TX part ******/ SemaphoreHandle_t xHandleSemaphoreTX = NULL; @@ -50,11 +54,7 @@ void XBEE_Init(void) { xSemaphoreGive(xHandleSemaphoreTX); rxBuffer=(uint8_t*)malloc(XBEE_RX_BUFFER_MAX_LENGTH); - rxBufferIndex=0; - - if(HAL_UART_Receive_IT(&hlpuart1, rxBuffer, 1)!= HAL_OK) { - while(1); - } + rxWaitForACK = 0; } /**** Support functions ****/ @@ -98,7 +98,7 @@ char* XBEE_EncodeWithEscapeChar(char* data, int length, int *encodedLength) { for (char* p=encodedData; p< (encodedData + *encodedLength); p++) { if ((*data == (char)XBEE_API_ESCAPE_CHAR) || (*data == (char)XBEE_API_START_OF_FRAME) || - (*data == (char)XBEE_API_XOFF) ||(*data == (char)XBEE_API_XON)) { + (*data == (char)XBEE_API_XOFF) ||(*data == (char)XBEE_API_XON)) { *p = (char) XBEE_API_ESCAPE_CHAR; p++; } @@ -119,10 +119,10 @@ char* XBEE_EncodeWithEscapeChar(char* data, int length, int *encodedLength) { * \return new buffer allocated without escaped char */ char* XBEE_DecodeWithoutEscapeChar(char* encodedData, int encodedLength, int *length) { - char* data = (char*)malloc(encodedLength); // on prevoit un buffer aussi grand que celui avec caractere d'echappement, - // au cas où aucun caractere d'echappement ne serait present - *length = encodedLength; // par defaut, on considére que les données brutes ont la même taille que - // celles avec caractéres d'echappement. + char* data = (char*)malloc(encodedLength); // on prévoit un buffer aussi grand que celui avec caractère d'echappement, + // au cas où aucun caractère d'echappement ne serait present + *length = encodedLength; // par défaut, on considère que les données brutes ont la même taille que + // celles avec caractères d'echappement. for (char* p=data; p< (data + encodedLength); p++) { if (*encodedData == (char)XBEE_API_ESCAPE_CHAR) { @@ -185,95 +185,94 @@ char* XBEE_EncodeTransmissionFrame(char* data, int length, uint16_t destination, return frame; } +/** + * Get frame length + * + * \param frame pointer on frame header + * \return length of incoming frame + */ +uint16_t XBEE_GetFrameLength(uint8_t *frame) { + return (((uint16_t)frame[1])<<8) + (uint16_t)frame[2]; +} + /** * Get a complete frame, check if frame is correct and extract raw data * - * \param frame pointer on complete frame - * \param data pointer to raw data, with escape char removed - * \param sender address of the sender - * \return status of decoding: XBEE_OK if decoding is successfull, XBEE_INVALID_FRAME otherwise + * \param raw_frame pointer on complete frame + * \param incomingFrame pointer to processed frame, with escape char removed + * \return status of decoding: XBEE_OK if decoding is successful, XBEE_INVALID_FRAME otherwise */ -XBEE_Status XBEE_DecodeFrame(char* frame, char** data, uint16_t *sender) { - uint8_t frame_type = (uint8_t)frame[3]; - uint16_t frame_length; +XBEE_Status XBEE_DecodeFrame(char* rawFrame, XBEE_INCOMING_FRAME** incomingFrame) { + uint8_t frame_type = (uint8_t)rawFrame[3]; + uint16_t rawFrameLength; uint8_t checksum; + XBEE_Status status = XBEE_OK; + int incomingDataLength = 0; + int i; - frame_length = (((uint16_t)frame[1])<<8) + (uint16_t)frame[2]; + if (rawFrame[0] == '~') { + rawFrameLength = (((uint16_t)rawFrame[1])<<8) + (uint16_t)rawFrame[2]; - /* verification du checksum */ - checksum =0; - for (i=3; i<3+frame_length+1; i++) { - checksum += (uint8_t)frame[i]; - } - - if (checksum != 0xFF) - return XBEE_INVALID_FRAME; - - switch (frame_type) { - case XBEE_RX_PACKET_TYPE: - *data = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_RX_PACKET_FRAME)+(frame_length-12)+1); // +1 for 0 ending in data frame - memset((void*)*data, 0, sizeof(XBEE_RX_PACKET_FRAME)+(frame_length-12)+1); - ((XBEE_RX_PACKET_FRAME*)(*data))->type = frame_type; - ((XBEE_RX_PACKET_FRAME*)(*data))->data_length = frame_length-12; - ((XBEE_RX_PACKET_FRAME*)(*data))->options = frame[14]; - - ((XBEE_RX_PACKET_FRAME*)(*data))->source_addr =0; - for (i=0; i<8; i++) { - ((XBEE_RX_PACKET_FRAME*)(*data))->source_addr = ((XBEE_RX_PACKET_FRAME*)(*data))->source_addr<<8; - ((XBEE_RX_PACKET_FRAME*)(*data))->source_addr +=(uint64_t)frame[4+i]; + /* verification du checksum */ + checksum =0; + for (i=3; i<3+rawFrameLength+1; i++) { + checksum += (uint8_t)rawFrame[i]; } - for (i=0; i<((XBEE_RX_PACKET_FRAME*)(*data))->data_length; i++) { - ((XBEE_RX_PACKET_FRAME*)(*data))->data[i] =(char)frame[15+i]; - } + if (checksum != 0xFF) + return XBEE_INVALID_FRAME; - ((XBEE_RX_PACKET_FRAME*)(*data))->data[((XBEE_RX_PACKET_FRAME*)(*data))->data_length]=0x0; // 0 ending frame + *incomingFrame = (XBEE_INCOMING_FRAME*) malloc(sizeof(XBEE_INCOMING_FRAME)); /* Allocate a generic frame struct */ + (*incomingFrame)->type = frame_type; - break; - case XBEE_MODEM_STATUS_TYPE: - *data = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_MODEM_STATUS_FRAME)); - ((XBEE_MODEM_STATUS_FRAME*)(*data))->type = frame_type; - ((XBEE_MODEM_STATUS_FRAME*)(*data))->status = frame[4]; + switch (frame_type) { + case XBEE_RX_16BIT_PACKET_TYPE: + /* Get source address */ + (*incomingFrame)->source_addr = (((uint16_t)rawFrame[4])<<8) + (uint16_t)rawFrame[5]; + (*incomingFrame)->data = XBEE_DecodeWithoutEscapeChar(&rawFrame[8], rawFrameLength-6, &incomingDataLength); + (*incomingFrame)->ack = 0; + break; - break; - case XBEE_TX_STATUS_TYPE: - case XBEE_EXTENDED_TX_STATUS_TYPE: - *data = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_TX_STATUS_FRAME)); - ((XBEE_TX_STATUS_FRAME*)(*data))->type = frame_type; - ((XBEE_TX_STATUS_FRAME*)(*data))->frame_id = frame[4]; - if (frame_type == XBEE_TX_STATUS_TYPE) { - ((XBEE_TX_STATUS_FRAME*)(*data))->status = frame[5]; - ((XBEE_TX_STATUS_FRAME*)(*data))->retry_count = 0; - } else { - ((XBEE_TX_STATUS_FRAME*)(*data))->status = frame[8]; - ((XBEE_TX_STATUS_FRAME*)(*data))->retry_count = frame[7]; - } + case XBEE_MODEM_STATUS_TYPE: + (*incomingFrame)->modem_status = rawFrame[4]; + (*incomingFrame)->data=0x0; + break; - break; - case XBEE_AT_CMD_RESPONSE_TYPE: - *data = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_AT_CMD_RESPONSE_FRAME)+(frame_length-5)); - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*data))->type = frame_type; - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*data))->data_length = frame_length-5; - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*data))->status = frame[7]; + case XBEE_TX_STATUS_TYPE: + (*incomingFrame)->ack = rawFrame[5]; + (*incomingFrame)->data=0x0; + break; - for (i=0; i<((XBEE_AT_CMD_RESPONSE_FRAME*)(*data))->data_length; i++) { - ((XBEE_AT_CMD_RESPONSE_FRAME*)(*data))->data[i] =(uint8_t)frame[8+i]; - } - break; - default: - *data = (XBEE_GENERIC_FRAME*)malloc(sizeof(XBEE_GENERIC_FRAME)); - ((XBEE_GENERIC_FRAME*)(*data))->type = frame_type; - return XBEE_INVALID_FRAME; - }; + case XBEE_EXTENDED_TX_STATUS_TYPE: + (*incomingFrame)->ack = rawFrame[8]; + (*incomingFrame)->data=0x0; + break; - return XBEE_OK; + default: + free (*incomingFrame); + return XBEE_INVALID_FRAME; + }; + } else status = XBEE_INVALID_FRAME; + + return status; } /**** TX Part *****/ + +/** + * Send data. Create a transmission frame, add escape char to data and send it over UART + * + * \param data raw data to send + * \param length length of data to send + * \return status of decoding: XBEE_OK if decoding is successful, + * XBEE_TX_ERROR in case of sending error, + * XBEE_TX_ACK_ERROR in case frame was not acknowledge by detination part + */ int XBEE_SendData(char* data, int length) { int data_length; BaseType_t state; + XBEE_INCOMING_FRAME* incomingFrame; // Prevents successive calls to overlap state = xSemaphoreTake(xHandleSemaphoreTX, pdMS_TO_TICKS(XBEE_TX_SEMAPHORE_WAIT)); // wait max 500 ms (to avoid interlocking) @@ -283,24 +282,44 @@ int XBEE_SendData(char* data, int length) { We should probably reset something in "else" branch */ /* TODO: stuff to do here for converting data into API frame */ - data_length = length; - if ((txBuffer = (uint8_t*)malloc(length))!=NULL) { - memcpy((void*)txBuffer, (void*) data, length); + txBuffer = (uint8_t*)XBEE_EncodeWithEscapeChar(data, length, &data_length); - if(HAL_UART_Transmit_IT(&hlpuart1, txBuffer, data_length)!= HAL_OK) - return -3; - } else return -2; - } else return -1; + if (txBuffer!=NULL) { + if (HAL_UART_Transmit_DMA(&hlpuart1, txBuffer, data_length)!= HAL_OK) + return XBEE_TX_ERROR; + else { + rxWaitForACK = 1; /* wait for TX ack */ + // Wait for ACK frame after TX + state = xSemaphoreTake(xHandleSemaphoreTX_ACK, pdMS_TO_TICKS(XBEE_TX_SEMAPHORE_WAIT)); // wait max 500 ms (to avoid interlocking) + if (XBEE_DecodeFrame((char*) rxBuffer, &incomingFrame)!=XBEE_OK) + return XBEE_TX_ACK_ERROR; + else { + if (incomingFrame == 0x0) + return XBEE_TX_ACK_ERROR; + else if ((incomingFrame->type != XBEE_TX_STATUS_TYPE) || (incomingFrame->ack != XBEE_TX_STATUS_SUCCESS)) { + free ((XBEE_INCOMING_FRAME*) incomingFrame); + return XBEE_TX_ACK_ERROR; + } + } + } + } else return XBEE_TX_ERROR; + } else return XBEE_TX_ERROR; return length; } +/** + * DMA Interrupt request for transmission. Call when transmission is finished + * + * \param UartHandle not used + */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* Do stuff here */ + /* Free transmit buffer */ free (txBuffer); - xSemaphoreGiveFromISR( xHandleSemaphoreTX, &xHigherPriorityTaskWoken ); + if (rxWaitForACK != 1) /* we are waiting for an acknowledge frame, so do not give semaphore yet */ + xSemaphoreGiveFromISR( xHandleSemaphoreTX, &xHigherPriorityTaskWoken ); /* If xHigherPriorityTaskWoken was set to true you we should yield. The actual macro used here is @@ -309,30 +328,60 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) { } /***** Rx Part *****/ + +/** + * Reception thread. Wait for incoming frame, process it and send message to application + * + * \param params not used + */ void XBEE_RxThread(void* params) { + BaseType_t state; + XBEE_INCOMING_FRAME* incomingFrame; + + rxPhase= XBEE_RX_PHASE_HEADER; + while (HAL_UART_Receive_DMA(&hlpuart1, rxBuffer, 3)== HAL_OK); // start reception of frame // endless task while (1) { + while ((state = xSemaphoreTake(xHandleSemaphoreRX, portMAX_DELAY))==pdTRUE); // wait forever + /* Process frame */ + if (XBEE_DecodeFrame((char*) rxBuffer, &incomingFrame)==XBEE_OK) // frame is valid + if (incomingFrame != 0x0) // frame is valid + MESSAGE_SendMailbox(APPLICATION_Mailbox, MSG_ID_XBEE_CMD, (QueueHandle_t)0x0, (void*)incomingFrame); } } +/** + * DMA IRQ handler for reception. Receive a complete frame send send event to sending frame in case of acknowledge frame or to receive task otherwise + * + * \param UartHandle not used + */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; + uint16_t frameLength; - if (rxBuffer[rxBufferIndex] == '\r') { - rxBuffer[rxBufferIndex+1]=0; // add end of string - MESSAGE_SendMailboxFromISR(APPLICATION_Mailbox, MSG_ID_XBEE_CMD, (QueueHandle_t)0x0, (void*)rxBuffer, &xHigherPriorityTaskWoken); + if (rxPhase == XBEE_RX_PHASE_HEADER) { // we just received header part + frameLength=XBEE_GetFrameLength(rxBuffer); /* Compute body part of the frame + checksum */ - rxBuffer = malloc(XBEE_RX_BUFFER_MAX_LENGTH); - rxBufferIndex=0; - } else if (rxBufferIndex>=XBEE_RX_BUFFER_MAX_LENGTH-2) // prevent buffer overflow - rxBufferIndex=0; - else - rxBufferIndex++; + if (HAL_UART_Receive_DMA(&hlpuart1, rxBuffer+3, frameLength+1)== HAL_OK) { + /* Reception of body part started successfully */ + rxPhase = XBEE_RX_PHASE_BODY; + } else { + /* Failed to start reception of body + * Restart reception of header */ + while (HAL_UART_Receive_DMA(&hlpuart1, rxBuffer, 3)!= HAL_OK); // try to receive header + } + } else { // we just received body part. Frame is complete + if (rxWaitForACK) { + xSemaphoreGiveFromISR( xHandleSemaphoreTX_ACK, &xHigherPriorityTaskWoken); /* Send event to sending function */ + xSemaphoreGiveFromISR( xHandleSemaphoreTX, &xHigherPriorityTaskWoken ); /* Allow new sending data */ + } else { + xSemaphoreGiveFromISR( xHandleSemaphoreRX, &xHigherPriorityTaskWoken ); /* send event to receive task to process received task */ + } - if(HAL_UART_Receive_IT(&hlpuart1, &rxBuffer[rxBufferIndex], 1)!= HAL_OK) { - while(1); + rxPhase = XBEE_RX_PHASE_HEADER; + while (HAL_UART_Receive_DMA(&hlpuart1, rxBuffer, 3)!= HAL_OK); // try to receive header } if (xHigherPriorityTaskWoken) { diff --git a/software/dumber3/Application/xbee.h b/software/dumber3/Application/xbee.h index e78e554..68e726f 100644 --- a/software/dumber3/Application/xbee.h +++ b/software/dumber3/Application/xbee.h @@ -12,12 +12,12 @@ typedef enum { XBEE_OK=0, - XBEE_CONFIG_ERROR, - XBEE_AT_CMD_ERROR, - XBEE_RX_TIMEOUT, - XBEE_RX_ERROR, - XBEE_TX_ERROR, - XBEE_INVALID_FRAME + XBEE_CONFIG_ERROR=-1, + XBEE_TX_ACK_ERROR=-2, + XBEE_RX_TIMEOUT=-3, + XBEE_RX_ERROR=-4, + XBEE_TX_ERROR=-5, + XBEE_INVALID_FRAME=-6 } XBEE_Status; #define XBEE_RX_PACKET_TYPE 0x90 @@ -50,37 +50,12 @@ typedef enum { #define XBEE_RX_OPTIONS_PAN_BROADCASTED 0x04 typedef struct { - uint8_t type; -} XBEE_GENERIC_FRAME; - -typedef struct { - uint8_t type; - uint64_t source_addr; - uint8_t options; - uint8_t data_length; - char data[]; -} XBEE_RX_PACKET_FRAME; - -typedef struct { - uint8_t type; - uint8_t frame_id; - uint16_t at_cmd; - uint8_t status; - uint8_t data_length; - char data[]; -} XBEE_AT_CMD_RESPONSE_FRAME; - -typedef struct { - uint8_t type; - uint8_t frame_id; - uint8_t status; - uint8_t retry_count; -} XBEE_TX_STATUS_FRAME; - -typedef struct { - uint8_t type; - uint8_t status; -} XBEE_MODEM_STATUS_FRAME; + uint8_t type; + uint16_t source_addr; + char* data; + char ack; + char modem_status; +} XBEE_INCOMING_FRAME; void XBEE_Init(void); int XBEE_SendData(char* data, int length);