Reworking the AVR specific stuff into an AVRInterface class.
This commit is contained in:
159
AVR Working Controller/AVRInterface.cpp
Normal file
159
AVR Working Controller/AVRInterface.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user