mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
177 lines
4.9 KiB
C
177 lines
4.9 KiB
C
/*
|
|
* uartcmd.c
|
|
*
|
|
* Created on: 20.03.2013
|
|
* Author: Willok
|
|
*
|
|
* ChangeLog
|
|
* 2019-09-22 Willok Added processing of UART command
|
|
*
|
|
*/
|
|
|
|
#include "Uart.h"
|
|
#include "uartcmd.h"
|
|
#include "Settings.h"
|
|
#include "Configuration.h"
|
|
#include "Application/Application.h"
|
|
|
|
#include "System.h"
|
|
|
|
|
|
uint16_t CmdLen = 0;
|
|
uint8_t CmdBuffer[256];
|
|
|
|
// Check Summing
|
|
uint8_t GetChkSum(PCMD_HEAD pCmdHead, uint8_t *DataPtr) {
|
|
uint8_t bRet = 0;
|
|
|
|
if (!DataPtr)
|
|
DataPtr = (uint8_t *)(pCmdHead + 1);
|
|
|
|
bRet -= pCmdHead->bSign;
|
|
bRet -= pCmdHead->bCmd;
|
|
bRet -= pCmdHead->bCmdLen;
|
|
|
|
for (uint8_t i = 0; i < pCmdHead->bCmdLen; i++) {
|
|
bRet -= DataPtr[i];
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// UART command initialization
|
|
void uartcmd_init(void) {
|
|
CmdLen = 0;
|
|
CmdBuffer[0] = 0;
|
|
}
|
|
|
|
|
|
|
|
// USBmode or UARTmode
|
|
extern uint8_t bUSBTerminal;
|
|
|
|
// Received UART command data. Need to be handed over to the command line
|
|
void CmdUartRx(PCMD_HEAD CmdHead, uint8_t *UartData) {
|
|
if (!bUSBTerminal) {
|
|
while (CmdHead->bCmdLen) {
|
|
if (XModemProcessByte(*UartData)) {
|
|
/* XModem handled the byte */
|
|
} else if (CommandLineProcessByte(*UartData)) {
|
|
/* CommandLine handled the byte */
|
|
}
|
|
|
|
UartData++;
|
|
CmdHead->bCmdLen--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Heartbeat marker
|
|
uint8_t bKeepAlive = 1;
|
|
|
|
// Version number with compilation date
|
|
char bVersion[] = "v1.0 " BUILD_DATE " " __TIME__;
|
|
|
|
// Command tick, send heartbeat packet regularly
|
|
void uartcmd_tick(void) {
|
|
static uint8_t KeepAliveTick = 200;
|
|
|
|
// heartbeat every 2S
|
|
if (++KeepAliveTick >= 20) {
|
|
KeepAliveTick = 0;
|
|
|
|
if (bKeepAlive) {
|
|
uint8_t Buffer[sizeof(CMD_HEAD) + sizeof(CMD_KEEP_ALIVE)];
|
|
PCMD_HEAD CmdHead = (PCMD_HEAD)Buffer;
|
|
PCMD_KEEP_ALIVE pKeepAlive = (PCMD_KEEP_ALIVE)(CmdHead + 1);
|
|
|
|
// Fill handshake package
|
|
CmdHead->bSign = 0xA5;
|
|
CmdHead->bCmd = CMD_TYPE_ALIVE;
|
|
CmdHead->bCmdLen = sizeof(CMD_KEEP_ALIVE);
|
|
pKeepAlive->bMajVer = 1;
|
|
pKeepAlive->bMinVer = 0;
|
|
memcpy(pKeepAlive->bVerStr, bVersion, sizeof(bVersion));
|
|
|
|
CmdHead->bChkSum = GetChkSum(CmdHead, NULL);
|
|
// Send handshake package
|
|
uart_putb((uint8_t *)CmdHead, sizeof(CMD_HEAD) + CmdHead->bCmdLen);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Receive shutdown notification
|
|
void CmdUartPowerDown(PCMD_HEAD CmdHead, uint8_t *UartData) {
|
|
// Switch to empty configuration, not saved
|
|
ConfigurationSetById(CONFIG_NONE);
|
|
|
|
// Save log on demand
|
|
LogTick();
|
|
|
|
// Flash two LED to warning power off
|
|
LED_PORT.OUTSET = PIN4_bm;
|
|
LED_PORT.OUTCLR = PIN3_bm;
|
|
while (1) {
|
|
if (SystemTick100ms()) {
|
|
LED_PORT.OUTTGL = PIN4_bm;
|
|
LED_PORT.OUTTGL = PIN3_bm;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Command processing callback
|
|
void uartcmd_task(void) {
|
|
int16_t RecvData;
|
|
// Loop data in receive buffer
|
|
while ((RecvData = uart_fifo_get()) >= 0) {
|
|
CmdBuffer[CmdLen] = (uint8_t)RecvData;
|
|
|
|
// The first character must be special, otherwise it will be discarded
|
|
if (CmdLen == 0 && CmdBuffer[0] != CMD_HEAD_SIGN)
|
|
continue;
|
|
|
|
|
|
// Statistics received
|
|
CmdLen++;
|
|
|
|
// At least one head is needed, then we can handle it.
|
|
if (CmdLen >= sizeof(CMD_HEAD)) {
|
|
PCMD_HEAD CmdHead = (PCMD_HEAD)CmdBuffer;
|
|
|
|
// If the command length is too long, there must be error. Discard the data and wait for resynchronization.
|
|
if (CmdHead->bCmdLen >= (sizeof(CmdBuffer) - sizeof(CMD_HEAD))) {
|
|
CmdLen = 0;
|
|
continue;
|
|
}
|
|
|
|
// Judge whether the received data is complete
|
|
if (CmdLen >= sizeof(CMD_HEAD) + CmdHead->bCmdLen) {
|
|
// Calculate the check sum, otherwise discard it.
|
|
if (CmdHead->bChkSum != GetChkSum(CmdHead, NULL)) {
|
|
CmdLen = 0;
|
|
continue;
|
|
}
|
|
|
|
// Processing command
|
|
switch (CmdHead->bCmd) {
|
|
case CMD_UART_RXTX: // Uart data
|
|
CmdUartRx(CmdHead, (uint8_t *)(CmdHead + 1));
|
|
break;
|
|
case CMD_TYPE_POWERDOWN: // Switch to empty configuration and wait for power failure
|
|
CmdUartPowerDown(CmdHead, (uint8_t *)(CmdHead + 1));
|
|
break;
|
|
case CMD_TYPE_ALIVE: // Receive the heartbeat package response, turn off the heartbeat
|
|
bKeepAlive = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Clear command buffer after command processing
|
|
CmdLen = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|