#pragma once #include class AVRInterface { public: /// @brief /// @param SendMessage is the function this AVRInterface calls to send a message to the device /// AVRInterface(bool (*SendMessage)(const uint8_t *buffer, uint16_t len)); ~AVRInterface(); /// @brief When the system receives something from the device, give it to this function to handle it /// @param buffer /// @param len /// @return true if it was handled /// bool HandleMessage(const uint8_t *buffer, uint16_t len); /// @brief Call this periodically so timed activities can be handled. /// /// Every 1 or even 50 to 100 msec is ok. /// /// @param millisec /// void Tick(uint32_t millisec); /// @brief Initialize the AVR interface and issue the ready command. /// /// This is temporarily blocking since nothing else should run until ready /// /// @return true if initialized /// bool Initialize(); /// @brief determine if the device is ready /// /// @return true if ready /// bool IsOnline(); typedef enum { eOn = 0, eOff, eStandby } AVROnOff_E; typedef enum { eUp, eDown, } AVRUpDown_E; typedef enum { eMuteOn, eMuteOff } AVRMute_E; typedef enum { eOSDOff, eOSDShort, eOSDFull } AVROSDScreen_E; typedef enum { eSleepOff, eSleep120, eSleep90, eSleep60, eSleep30 } AVRSleep_E; typedef enum { eOnMatrix, eESESOff, eAuto, eDiscrete } AVREX_ES_E; typedef enum { eEffectOn, eStereo } AVREffect_E; typedef enum { eFM, eAM } AVRTunerBand_E; typedef enum { e1, e2, e3, e4, e5, e6, e7, e8 } AVRPresetNum_E; typedef enum { eA, eB, eC, eD, eE, eF } AVRPresetPage_E; typedef enum { ePhono, eCD, eTuner, eCDR, eMD_Tape, eDVD, eDTV, eCable, eSat, eVCR1, eVCR2_DVR, eVCR3, eV_Aux, } AVRInput_E; typedef enum { eMain, eZone1, eZone2, eZone3, eZoneOR } AVRSubsystem_E; typedef enum { Hall_A, Hall_B, Hall_C, Hall_USA, Hall_E, Live_Concert, Tokyo, Freiburg, Royaumont, Village_Gate, Village_Vanguard, The_Bottom_Line, The_Roxy_Theater, Warehouse_Loft, Arena, Disco, Party, Game, Stereo_6_8Ch, Pop_Rock, DJ, Opera, Pavillion, Mono_Movie, Variety_Sports, Spectacre, Sci_Fi, Adventure, General, Normal, Enhanced, PLII_Movie, PLII_Music, Neo_6_Movie, Neo_6_Music, Direct_2Ch, Stereo_2Ch, THX_Ultra_PL, THX_Music, THX_Ultra_PL2, THX_Ultra_NEO6 } AVRDSPProg_E; typedef enum { eInpAuto, eDD_RF, eDTS, eDigital, eAnalog, eAAC } AVRInputMode_E; typedef enum { eDualMain, eDualSub, eDualAll } AVRDualMono_E; typedef enum { fncPower, fncVolume, fncMute, fncVolumeMemory, fncVolumeRecall, fncSpeakerAOnOff, fncSpeakerBOnOff, fncSpeakerBZone, fncZone2SpeakerOnOff, fncNightModeOnOff, fncEffect, fncInput, fncRadioBand, fncRadioTune, fncRadioPresetPage, fncRadioPresetNumber, fncRadioPresetMemory, fncRadioPresetRecall, fncDSPProgram, fncSleep, fncOSD, fnc6ChInput, fncEx_EsOnOff, fncInputMode, fncDualMono, fncDC1TrigControl, fncDC2TrigControl, fncDC1OnOff, fncDC2OnOff, } AVRFunction_E; typedef union { AVROnOff_E onOff; AVRUpDown_E volume; AVRMute_E mute; AVRPresetPage_E volumeMemory; AVRPresetPage_E volumeRecall; AVROnOff_E speakerA; AVROnOff_E speakerB; AVRSubsystem_E speakerBZone; AVROnOff_E zone2Speaker; AVROnOff_E nightMode; AVRInput_E input; AVRTunerBand_E band; AVRUpDown_E tune; AVRPresetPage_E presetPage; AVRPresetNum_E presetNumber; AVRPresetPage_E presetMemory; AVRPresetPage_E presetRecall; AVRDSPProg_E program; AVRSleep_E sleep; AVROSDScreen_E osd; AVROnOff_E sixChInput; AVREX_ES_E ex_es; AVRInputMode_E inputMode; AVRDualMono_E dualMono; AVRSubsystem_E dc1TrigControl; AVRSubsystem_E dc2TrigControl; AVROnOff_E dc1OnOff; AVROnOff_E dc2OnOff; char *pMessage; } AVRArgument_UX; typedef uint32_t AVRArg_T; /// @brief The single command path to control the AVR /// /// This lets you send a command to the AVR using this single interface, by choosing /// the AVR Subsystem of interest, the Function of interest, and passing an argument. /// /// @param[in] subsystem: Main | Zone 1 | Zone 2 | Zone 3 /// @param[in] function : Power, Speaker, Volume, etc. /// @param[in] arg: on/off, etc. /// @return bool AVRCommand(AVRInterface::AVRSubsystem_E subsystem, AVRInterface::AVRFunction_E function, AVRArg_T arg); /// @brief Send the power command /// @param cmd /// @return true /// bool Power(AVROnOff_E cmd); bool VolumeButton(AVRUpDown_E cmd); /// @brief AVRMessageType_T /// /// Indicates the type of message being sent to the status change callback /// typedef enum { mtModelInfo, ///?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz" /// @return true if the message was accepted for sending, false if it is too long or has invalid characters. /// bool AVRSendOSDMessage(const char *msg); private: uint32_t sentAtTime_ms; typedef enum { stPoweringUp, stAwaitingReadyResponse, stInitializing, stRetryInitializing, stReady, stAwaitingResponse, stMaxStates } AVRState_T; AVRState_T state = stPoweringUp; AVRState_T oldState = stMaxStates; AVRState_T GetState() { return state; } // Each DT is the hex-character from the stream // // This could be simplified to uint8_t DT[138] // typedef struct { uint8_t DT0; // * Baud Rate '@' uint8_t DT1; // * Receive Buffer 'E' uint8_t DT2; // * Receive Buffer '0' uint8_t DT3; // * '1' uint8_t DT4; // * Command Timeout '9' uint8_t DT5; // * '0' uint8_t DT6; // * '0' uint8_t DT7; // * System '0':Ok, '1':Busy uint8_t DT8; // * Power 0:Off, 1:On uint8_t DT9; // Input 0: Phono, 1:CD, 2:Tuner, 3:CD-R, 4:MD-Tape, 5:DVD, 6:D-TV, 7:Cbl, 9:VCR1, A:VCR2 uint8_t DT10; // 6ch input 0:Off, 1:On uint8_t DT11; // Input Mode 0:AUTO, 2:DTS, 4:Analog, 5:Analog Only uint8_t DT12; // Audio Mute 0:Off, 1:On uint8_t DT13; // Zone2 Input 0: PHONO / 1: CD / 2: TUNER / 3: CD-R / 4: MD-TAPE / 5: DVD / 6: D-TV-LD / 7: CBL-SAT / 9: VCR1 / A: VCR2-DVR / C: V-AUX uint8_t DT14; // Zone2 Mute 0: OFF / 1: ON uint8_t DT15; // Master Volume Upper 4 bit uint8_t DT16; // Master Volume Lower 4 bit uint8_t DT17; // Zone2 Volume Upper 4 bit uint8_t DT18; // Zone2 Volume Lower 4 bit uint8_t DT19; // Program Upper 4 bit uint8_t DT20; // Program Lower 4 bit uint8_t DT21; // Effect 0: OFF / 1: ON uint8_t DT22; // 6.1/ES key status 0: OFF / 1: MATRIX ON / 2: DISCRETE ON / 3: AUTO uint8_t DT23; // OSD* 0: FULL / 1: SHORT / 2: OFF uint8_t DT24; // Sleep 0: 120 / 2: 90 / 3: 60 / 4: 30 / 5: OFF uint8_t DT25; // Tuner Page 0: Page A / 1: Page B / 2: Page C / 3: Page D / 4: PageE uint8_t DT26; // Tuner No. 0: No.1 / 1: No.2 / 2: No.3 / 3: No.4 / 4: No.5 / 5: No.6 / 6: No.7 / 7: No.8 uint8_t DT27; // Night mode 0: OFF / 1: ON uint8_t DT28; // Care uint8_t DT29; // Speaker relay A 0: OFF / 1: ON uint8_t DT30; // Speaker relay B 0: OFF / 1: ON uint8_t DT31; // Playback 0: 6ch input / 1: Analog / 2: PCM / 3: DD*(except 2.0) / 4: DD(2.0) / 5: DD.Karaoke / 6: DD.EX / 7: DTS / 8: DTS-ES / 9: Other DIGITAL / A: DTS Analog Mute / B: DTS ES Discrete uint8_t DT32; // Fs 0: Analog / 1: 32kHz / 2: 44.1kHz / 3: 48kiHz / 4: 64kHz / 5: 88.2kHz / 6: 96kHz / 7: Unknown B: DTS 96/24 uint8_t DT33; // EX/ES playback 0: OFF / 1: MATRIX ON / 2: DISCRETE ON uint8_t DT34; // Thr / Bypass 0: Normal / 1: Bypass uint8_t DT35; // RED dts 0: Release / 1: Wait uint8_t DT36; // Head Phone 0: OFF / 1: ON uint8_t DT37; // TUNER BAND 0: FM / 1: AM uint8_t DT38; // TUNER TUNED 0: NOT TUNED / 1: TUNED uint8_t DT39; // DC1 Control Out 0: LOW / 1: HIGH uint8_t DT40; // Don’t care uint8_t DT41; // Don't Care uint8_t DT42; // 0-2 DC1 TRG Ctrl. 0: Zone1 / 1: Zone2 / 2: Zone1&2 uint8_t DT43; // 0/1 dts 96/24 0: OFF / 1: ON uint8_t DT44; // 0-2 DC2 TRG Ctrl. 0: Zone1 / 1: Zone2 / 2: Zone1&2 uint8_t DT45; // 0/1 DC2 Trigger 0: LOW / 1: HIGH uint8_t DT46; // SP B set 0: Zone1 / 1: Zone2 uint8_t DT47; // Zone 2 SP out 0: OFF / 1: ON uint8_t DT48; // MAIN R Upper 4bit uint8_t DT49; // Lower 4bit uint8_t DT50; // MAIN L Upper 4bit uint8_t DT51; // Lower 4bit uint8_t DT52; // CENTER Upper 4bit uint8_t DT53; // Lower 4bit uint8_t DT54; // REAR R Upper 4bit uint8_t DT55; // Lower 4bit uint8_t DT56; // REAR L Upper 4bit uint8_t DT57; // Lower 4bit uint8_t DT58; // SUR BACK Upper 4bit uint8_t DT59; // R Lower 4bit uint8_t DT60; // SUR BACK Upper 4bit uint8_t DT61; // L Lower 4bit uint8_t DT62; // FRONT R Upper 4bit uint8_t DT63; // Lower 4bit uint8_t DT64; // FRONT L Upper 4bit uint8_t DT65; // Lower 4bit uint8_t DT66; // SWFR 1 Upper 4bit uint8_t DT67; // Lower 4bit uint8_t DT68; // Don't Care uint8_t DT69; // Don't Care uint8_t DT70; // Don't Care uint8_t DT71; // Don't Care uint8_t DT72; // Don't Care uint8_t DT73; // Don't Care uint8_t DT74; // LFE Lvl. SP Upper 4bit uint8_t DT75; // Lower 4bit uint8_t DT76; // LFE Lvl. HP Upper 4bit uint8_t DT77; // Lower 4bit uint8_t DT78; // Audio Delay Upper 4bit uint8_t DT79; // Lower 4bit uint8_t DT80; // Don't Care uint8_t DT81; // Don't Care uint8_t DT82; // Don't Care uint8_t DT83; // Don't Care uint8_t DT84; // Input mode set 0: AUTO / 1: LAST uint8_t DT85; // Dimmer 0: -4 / 1: -3 / 2: -2 / 3: -1 / 4: 0 uint8_t DT86; // OSD Message uint8_t DT87; // OSD shift Upper 4bit uint8_t DT88; // Lower 4bit uint8_t DT89; // Glay back 0: OFF / 1: AUTO uint8_t DT90; // Video conversion 0: OFF / 1: ON uint8_t DT91; // D. Range SP 0: MAX / 1: STD / 2: MIN uint8_t DT92; // HP 0: MAX / 1: STD / 2: MIN uint8_t DT93; // Zone 2 vol. Out uint8_t DT94; // Don't Care uint8_t DT95; // Memory guard 0: OFF / 1: ON uint8_t DT96; // SP set Center 0: Large / 1: Small / 2: None uint8_t DT97; // Main 0: Large / 1: Small uint8_t DT98; // Rear L/R 0: Large / 1: Small / 2: None uint8_t DT99; // Rear CT 0: Large / 1: Small / 2: None uint8_t DT100; // Front 0: Yes / 1: None uint8_t DT101; // LFE/BASS 0: SWFR / 1: Main / 2: Both uint8_t DT102; // 6CH Center 0: Center / 1: Main uint8_t DT103; // SWFR 0: SWFR / 1: Main uint8_t DT104; // Main level 0: Normal / 1: -10dB uint8_t DT105; // Test mode 0: OFF / 1: Dolby / 2: DTS uint8_t DT106; // Don't Care uint8_t DT107; // LVL 6CH MAIN L Upper 4bit uint8_t DT108; // Lower 4bit uint8_t DT109; // MAIN R Upper 4bit uint8_t DT110; // Lower 4bit uint8_t DT111; // CENTER Upper 4bit uint8_t DT112; // Lower 4bit uint8_t DT113; // SL Upper 4bit uint8_t DT114; // Lower 4bit uint8_t DT115; // SR Upper 4bit uint8_t DT116; // Lower 4bit uint8_t DT117; // SBL Upper 4bit uint8_t DT118; // Lower 4bit uint8_t DT119; // SBR Upper 4bit uint8_t DT120; // Lower 4bit uint8_t DT121; // FRONT L Upper 4bit uint8_t DT122; // Lower 4bit uint8_t DT123; // FRONT R Upper 4bit uint8_t DT124; // Lower 4bit uint8_t DT125; // SWFR Upper 4bit uint8_t DT126; // Lower 4bit uint8_t DT127; // 0 - C Z3 Input uint8_t DT128; // 0/1 Z3 Mute uint8_t DT129; // 0 - F Z3 Volume Upper 4bit uint8_t DT130; // 0 - F Lower 4bit uint8_t DT131; // Don't Care uint8_t DT132; // MULTI_CH SELECT 00:6CH / 01:8CH TUNER / 02: 8CH CD / 04: 8CH CD-R / 05: 8CH DVD / 06: DTV / 07: 8CH CBL/SAT / 09: 8CH VCR1 / 0A: VCR2/DVR / 0C: VAUX uint8_t DT133; // MULTI_CH SURROUND to 00: Surround / 01: Main uint8_t DT134; // SP SET SW1 00: L-R / 01: F-R / 02: NONE uint8_t DT135; // SP SET CROSSOVER 00: 40Hz / 01: 60Hz / 02: 80Hz / 03: 90Hz / 04: 100Hz / 05: 110Hz / 06: 120Hz / 07: 160Hz / 08: 200Hz uint8_t DT136; // COMPONENT OSD 00: OFF / 01: ON uint8_t DT137; // PB/SB SELECT 00: PR / 01: SB uint8_t DT138[100]; // From here on is just buffer in case it sends more data } AVR_Configuration_T; typedef struct { uint8_t type[5]; // Model ID uint8_t version; // A-Z uint8_t length[2]; // 1 - 255 } AVR_StatusHeader_T; typedef struct { bool headerValid; bool configValid; AVR_StatusHeader_T header; AVR_Configuration_T config; } AVR_Status_T; //AVR_StatusHeader_T avrStatusHeader; //AVR_Configuration_T avrConfigData; AVR_Status_T avrStatus; bool commandResponseReceived; // a response to the last command was received bool readyResponsReceived; // the special system ready response was received int readyTries; #define RETRY_INTERVAL_ms 500 #define MAXTRIES 5 #define SERIALQUEUESIZE 5 typedef struct { uint8_t *messageToSend; uint16_t len; } SerialQueue_T; SerialQueue_T serialQueue[SERIALQUEUESIZE]; int serialQueueCount = 0; bool bFirstTickInitialized; uint32_t firstTick_ms; // basically the time when the program started uint32_t lastTick_ms; // @TODO instead of this, offer a way for the class to get the current time bool IsSanityCheckOK(); void MessageHandlerSanityCheck(); // host provided method to send to the AVR bool (*SendMethod)(const uint8_t *buffer, uint16_t bufferSize); // host provided method to update the user with a text message void(*ReportInformation)(AVRMessageType_T type, const char * message); void PCMessage(const char *msg, int len, uint8_t **src, const char *(fncHelper)(uint8_t val) = NULL); bool ProcessReportResponse(const uint8_t *szBuffer, uint32_t len); void MessageReport(const char *prefix, const void *buf, size_t len = 0); bool CheckTheChecksum(const uint8_t *szBuffer, uint32_t num); uint16_t Hex2Dec(const uint8_t *p, int dig); void FreeMemory(); };