Files
AVR/AVR Working Controller/AVRInterface.cpp

160 lines
3.6 KiB
C++

#include <memory.h>
#include <malloc.h>
#include "AVRInterface.h"
//AVRInterface::AVRInterface(int (*SendMessage)(const void *buffer, unsigned int bufferSize)) {
//}
AVRInterface::~AVRInterface() {
FreeMemory();
}
void AVRInterface::Tick(uint32_t now_ms) {
uint32_t elapsed_ms = now_ms - sentAtTime_ms;
switch (state) {
default:
case AVRState_T::stPoweringUp:
readyResponsReceived = false;
ProcessSerialQueue((uint8_t *)"\x11" "000" "\x03", 5); // Send the Ready Command
sentAtTime_ms = now_ms;
readyTries++;
state = stAwaitingReadyResponse;
break;
case stAwaitingReadyResponse:
if (readyResponsReceived) {
state = stReady;
} else if (elapsed_ms > RETRY_INTERVAL_ms) {
if (readyTries > MAXTRIES) {
// fail
} else {
state = stPoweringUp;
}
}
break;
case AVRState_T::stInitializing:
break;
case AVRState_T::stRetryInitializing:
break;
case AVRState_T::stAwaitingResponse:
break;
case AVRState_T::stReady:
ProcessSerialQueue();
break;
}
}
bool AVRInterface::HandleMessage(const uint8_t *buffer, uint16_t len) {
switch (state) {
case stAwaitingReadyResponse:
switch (buffer[0]) {
case 0x02: // STX <msg> ETX
break;
case 0x11: // DC1 <msg> ETX
break;
case 0x12: // DC2 <msg> ETX
if (CheckTheChecksum(buffer, len)) {
readyResponsReceived = true;
}
break;
case 0x14: // DC4 <extended response> ETX
break;
default:
break;
}
readyResponsReceived = true;
break;
case stReady:
break;
}
return true;
}
bool AVRInterface::Initialize() {
return true;
}
bool AVRInterface::IsOnline() {
return true;
}
bool AVRInterface::Power(AVRPower_T cmd) {
return true;
}
bool AVRInterface::MasterVolumeButton(AVRVolumeButton_T cmd) {
return true;
}
bool AVRInterface::Mute(AVRMute_T cmd) {
return true;
}
bool AVRInterface::ProcessSerialQueue(const uint8_t *p, uint16_t len) {
bool retVal = false; // assume fail
static bool freshData = false;
if (p && len) {
if (serialQueueCount < SERIALQUEUESIZE) {
serialQueue[serialQueueCount].messageToSend = (uint8_t *)malloc(len);
if (serialQueue[serialQueueCount].messageToSend) {
memcpy(serialQueue[serialQueueCount].messageToSend, p, len);
serialQueue[serialQueueCount].len = len;
serialQueueCount++;
retVal = true;
freshData = true;
}
}
}
if (serialQueueCount) {
if ((*SendMethod)((const uint8_t *)serialQueue[0].messageToSend, serialQueue[0].len)) {
--serialQueueCount;
free(serialQueue[0].messageToSend);
serialQueue[0].messageToSend = NULL;
for (int i = 0; i < serialQueueCount; i++) {
serialQueue[i] = serialQueue[i + 1];
}
retVal = true;
}
}
return retVal;
}
void AVRInterface::FreeMemory() {
for (int i = 0; i < serialQueueCount; i++) {
if (serialQueue[0].messageToSend)
free(serialQueue[0].messageToSend);
}
}
bool AVRInterface::CheckTheChecksum(const uint8_t *szBuffer, uint32_t num) {
uint8_t sum = 0;
for (uint16_t i = 1; i < num - 3; i++) {
sum += szBuffer[i];
}
uint8_t cksum = (uint8_t)Hex2Dec(&szBuffer[num - 3], 2);
//printf("CheckSum: %02X v. %c%c\n", sum, szBuffer[num - 3], szBuffer[num - 2]);
return (sum == cksum);
}
// Hex2Dec
//
// All responses are pretty much Hex-ASCII, so
// we sometimes want to convert it to decimal
// This takes a buffer and converts the specified
// number of characters.
//
unsigned long AVRInterface::Hex2Dec(const uint8_t *p, int dig) {
unsigned long x = 0;
while (dig--) {
if (*p >= '0' && *p <= '9')
x = x * 16 + *p - '0';
else if (*p >= 'a' && *p <= 'f')
x = x * 16 + 0x0a + *p - 'a';
else if (*p >= 'A' && *p <= 'F')
x = x * 16 + 0x0a + *p - 'A';
p++;
}
return x;
}