Fahad Mirza
/
Nucleo_HXC900
A demo application for HXC900 LoRaWAN module using Nucleo-L053R8.
Diff: LoRa/hxc_client.c
- Revision:
- 32:2d0678039a09
- Parent:
- 21:f1d561ed31a1
- Child:
- 33:83cd24bbb17a
diff -r 174c745f921c -r 2d0678039a09 LoRa/hxc_client.c --- a/LoRa/hxc_client.c Mon Dec 10 19:54:23 2018 +0000 +++ b/LoRa/hxc_client.c Thu Jan 24 21:57:23 2019 +0000 @@ -57,13 +57,36 @@ #include "time_server.h" #include "hw_gpio.h" + +/* Private macro -------------------------------------------------------------*/ +#define AT_VPRINTF(...) at_cmd_vprintf(__VA_ARGS__) +#define AT_VSSCANF(...) tiny_sscanf(__VA_ARGS__) + +#define BAUD_RATE 9600U +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define AT_RESPONSE_BUFF_SIZE 64U // Max size of the received buffer. +#define DATA_TX_MAX_BUFF_SIZE 78U // Max size of the transmit buffer +#define HXC_TIMEOUT 2000U // 2 seconds + + +// These strings will be used to compare the responses return from HXC modem. +// In direct relation with sAtRetCode_t +#define OK "OK" +#define ERROR "AT_ERROR" +#define PARAM_ERROR "AT_PARAM_ERROR" +#define BUSY_ERROR "AT_BUSY_ERROR" +#define PARAM_OVERFLOW "AT_PARAM_OVERFLOW" +#define INVALID_MODE "AT_INVALID_MODE" +#define NO_NETWORK_JOINED "AT_NO_NETWORK_JOINED" +#define PAYLOAD_SIZE_ERROR "AT_PAYLOAD_SIZE_ERROR" + + /* Private typedef -----------------------------------------------------------*/ // Type definition for return code analysis -typedef char* AtErrorStr_t; - typedef struct sAtRetCode { - AtErrorStr_t RetCodeStr; + char* RetCodeStr; uint8_t SizeRetCodeStr; eAtStatus_t RetCode; }sAtRetCode_t; @@ -74,47 +97,22 @@ static uint16_t at_set_cmd_format(ATCmd_t Cmd, const void *ptr); static eAtStatus_t at_cmd_send(uint16_t len); static eAtStatus_t at_cmd_receive(void *pdata); -static eAtStatus_t at_cmd_responseAnalysing(const char *ReturnResp); +static eAtStatus_t at_cmd_analyzeResponse(const char *ReturnResp); static uint16_t at_cmd_vprintf(const char *format, ...); -/* Private macro -------------------------------------------------------------*/ -#define AT_VPRINTF(...) at_cmd_vprintf(__VA_ARGS__) -#define AT_VSSCANF(...) tiny_sscanf(__VA_ARGS__) - -#define BAUD_RATE 9600 -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -#define DATA_RX_MAX_BUFF_SIZE 64 /* Max size of the received buffer. - * To optimize we can match with device key sizeof */ - -#define DATA_TX_MAX_BUFF_SIZE 78 // Max size of the transmit buffer -#define HXC_TIMEOUT 2000 // 2 seconds - -/* - * RetCode used to compare the return code from HXC modem. - * In direct relation with sAtRetCode_t - */ -#define RET_OK "OK" -#define RET_ERROR "AT_ERROR" -#define RET_PARAM_ERROR "AT_PARAM_ERROR" -#define RET_BUSY_ERROR "AT_BUSY_ERROR" -#define RET_PARAM_OVERFLOW "AT_PARAM_OVERFLOW" -#define RET_INVALID_MODE "AT_INVALID_MODE" -#define RET_NO_NETWORK_JOINED "AT_NO_NETWORK_JOINED" -#define RET_PAYLOAD_SIZE_ERROR "AT_PAYLOAD_SIZE_ERROR" - - /* Private Variables --------------------------------------------------------*/ +// NOTE: sizeof of a string take account of the NULL character too, unlike +// strlen(). Hence subtract one from the sizeof. static const sAtRetCode_t AT_RetCode[] = { -{RET_OK, sizeof(RET_OK), AT_OK}, -{RET_ERROR, sizeof(RET_ERROR), AT_ERROR}, -{RET_PARAM_ERROR, sizeof(RET_PARAM_ERROR), AT_PARAM_ERROR}, -{RET_NO_NETWORK_JOINED, sizeof(RET_NO_NETWORK_JOINED), AT_NO_NET_JOINED}, -{RET_BUSY_ERROR, sizeof(RET_BUSY_ERROR), AT_BUSY_ERROR}, -{RET_PARAM_OVERFLOW, sizeof(RET_PARAM_OVERFLOW), AT_PARAM_OVERFLOW}, -{RET_INVALID_MODE, sizeof(RET_INVALID_MODE), AT_INVALID_MODE}, -{RET_PAYLOAD_SIZE_ERROR, sizeof(RET_PAYLOAD_SIZE_ERROR), AT_PAYLOAD_SIZE_ERROR}}; +{OK, sizeof(OK) - 1, AT_OK}, +{ERROR, sizeof(ERROR) - 1, AT_ERROR}, +{PARAM_ERROR, sizeof(PARAM_ERROR) - 1, AT_PARAM_ERROR}, +{NO_NETWORK_JOINED, sizeof(NO_NETWORK_JOINED) - 1, AT_NO_NET_JOINED}, +{BUSY_ERROR, sizeof(BUSY_ERROR) - 1, AT_BUSY_ERROR}, +{PARAM_OVERFLOW, sizeof(PARAM_OVERFLOW) - 1, AT_PARAM_OVERFLOW}, +{INVALID_MODE, sizeof(INVALID_MODE) - 1, AT_INVALID_MODE}, +{PAYLOAD_SIZE_ERROR, sizeof(PAYLOAD_SIZE_ERROR) - 1, AT_PAYLOAD_SIZE_ERROR}}; /* @@ -161,20 +159,17 @@ "+TXCW", // Continuous Tx "+TX", // Send LoRa only data in raw format "+RX", // Continuous Rx - "+BAT", /// Battery level + "+BAT", // Battery level "+VER", // Firmware version of the HXC Client }; -char LoRa_AT_Cmd_Buff[DATA_TX_MAX_BUFF_SIZE];// Buffer used for AT cmd transmission - -static uint16_t Offset = 0; // Write position needed for LoRa_AT_Cmd_Buff[] during AT_SET +static char AtCmdBuff[DATA_TX_MAX_BUFF_SIZE]; +// Write position needed for AtCmdBuff[] during AT_SET +static uint16_t Offset = 0; -/* Has to be the largest of the response. - * Not only for return code but also for - * return value e.g. APPKEY. - */ -static char response[DATA_RX_MAX_BUFF_SIZE]; +// Has to be the largest of the response e.g. APPKEY. +static char AtResponseBuff[AT_RESPONSE_BUFF_SIZE]; /* Exported functions ------------------------------------------------------- */ @@ -228,27 +223,24 @@ uint16_t atCmdLen; // Reset At_cmd buffer for each transmission - memset1((uint8_t *)LoRa_AT_Cmd_Buff, 0x00, sizeof(LoRa_AT_Cmd_Buff)); + memset1((uint8_t *)AtCmdBuff, 0x00, DATA_TX_MAX_BUFF_SIZE); - /* Reset the UART circular buffer for each transmission to make sure - * the responses we will get are for the current AT cmd. */ + // Reset the UART circular buffer for each transmission to make sure + // the responses we will get are for the current AT cmd. HW_UART_ResetBuffer(); // Format AT cmd atCmdLen = at_cmd_format(at_group, atCmd, pdata); if(atCmdLen == 0) { - /* - * You are trying to use a command behavior that HXC Client doesn't - * support. Check manual for possible AT command behaviors. - */ + // You are trying to use a command behavior that HXC Client doesn't + // support. Check manual for possible AT command behaviors. return AT_CMD_ERROR; } // Send AT cmd string if(at_cmd_send(atCmdLen) != AT_OK) { - // Problem on UART transmission return AT_UART_LINK_ERROR; } @@ -407,7 +399,7 @@ static eAtStatus_t at_cmd_send(uint16_t len) { /*transmit the command from master to slave*/ - if( HW_UART_Modem_SendBytes(LoRa_AT_Cmd_Buff, len) == false) + if( HW_UART_Modem_SendBytes(AtCmdBuff, len) == false) { return AT_UART_LINK_ERROR; } @@ -428,7 +420,7 @@ eAtStatus_t RetCode = AT_END_ERROR; // Cleanup the response buffer - memset1((uint8_t *)response, 0x00, sizeof(response)); + memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE); uint32_t currentTime = TimerGetCurrentTime(); while(ResponseComplete != true) @@ -443,22 +435,18 @@ } else { - // Process the response - response[i++] = HW_UART_Modem_GetNewChar(); + AtResponseBuff[i++] = HW_UART_Modem_GetNewChar(); // Wait up to line feed marker - if (response[i - 1] == '\n') + if (AtResponseBuff[i - 1] == '\n') { // Last two bytes are <CR><LF>, set CR as NULL byte. - response[i - 2] = '\0'; - // Reset index + AtResponseBuff[i - 2] = '\0'; i = 0; - // Compare response with AT statuses - RetCode = at_cmd_responseAnalysing(response); + RetCode = at_cmd_analyzeResponse(AtResponseBuff); if(RetCode != AT_END_ERROR) { - // We received a status. Response complete. ResponseComplete = true; } else if(pdata != NULL) @@ -466,14 +454,14 @@ // If pdata isn't null that means we are using GET cmd to get // return value. Copy the return value into pdata. - strcpy(pdata, response); - memset1((uint8_t *)response, 0x00, 16); + strcpy(pdata, AtResponseBuff); + memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE); // Now, let's get the status } } else { - if (i == (DATA_RX_MAX_BUFF_SIZE-1)) + if (i == (AT_RESPONSE_BUFF_SIZE - 1)) { // Frame overflow. Reset index and stop reading. i = 0; @@ -494,13 +482,13 @@ * @Param : response: pointer to the received response * @Return: eAtStatus_t error type *******************************************************************************/ -static eAtStatus_t at_cmd_responseAnalysing(const char *ReturnResp) +static eAtStatus_t at_cmd_analyzeResponse(const char *ReturnResp) { - int i; + uint8_t i; for (i = 0; i < ARRAY_SIZE(AT_RetCode); i++) { - if (strncmp(ReturnResp, AT_RetCode[i].RetCodeStr, (AT_RetCode[i].SizeRetCodeStr-1)) == 0) + if (strncmp(ReturnResp, AT_RetCode[i].RetCodeStr, (AT_RetCode[i].SizeRetCodeStr)) == 0) { /* Command has been found */ return AT_RetCode[i].RetCode; @@ -515,14 +503,14 @@ * @Param : Pointer to the format string * @Return: Length of the string to be sent *******************************************************************************/ -uint16_t at_cmd_vprintf(const char *format, ...) +static uint16_t at_cmd_vprintf(const char *format, ...) { va_list args; uint16_t len; va_start(args, format); - len = tiny_vsnprintf_like(LoRa_AT_Cmd_Buff+Offset, sizeof(LoRa_AT_Cmd_Buff)-Offset, format, args); + len = tiny_vsnprintf_like(AtCmdBuff + Offset, DATA_TX_MAX_BUFF_SIZE - Offset, format, args); va_end(args); @@ -556,13 +544,20 @@ return false; } // Cleanup the response buffer - memset1((uint8_t *)response, 0x00, sizeof(response)); - HW_UART_Modem_GetCharactersUntilNewLine(response, sizeof(response), HXC_TIMEOUT); - if(strncmp("rxdata", response, 6) == 0) + memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE); + + HW_UART_Modem_GetCharactersUntilNewLine(AtResponseBuff, AT_RESPONSE_BUFF_SIZE, HXC_TIMEOUT); + + if(strncmp("rxdata", AtResponseBuff, 6) == 0) { return true; } return false; } + +char* Modem_GetResponseBuffer(void) +{ + return AtResponseBuff; +} /************************ (C) COPYRIGHT Haxiot *****END OF FILE*****/