#include #include #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 ETX break; case 0x11: // DC1 ETX break; case 0x12: // DC2 ETX if (CheckTheChecksum(buffer, len)) { readyResponsReceived = true; } break; case 0x14: // DC4 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; }