diff --git a/src/avclandrv.c b/src/avclandrv.c index 6a0745a..6edefc5 100644 --- a/src/avclandrv.c +++ b/src/avclandrv.c @@ -94,7 +94,9 @@ #include #include #include +#include +#define VAR_DECLS #include "avclandrv.h" #include "com232.h" @@ -131,6 +133,7 @@ #define TCB_CNTMODE TCB_CNTMODE_PW_gc #endif +#define MAX_SEND_ATTEMPTS 3 uint8_t printAllFrames; uint8_t verbose; @@ -153,79 +156,19 @@ uint16_t period = 0; uint16_t pulsewidth; -#define SW_ID 0x11 // 11 For my stereo - -// commands -const uint8_t stat1[] = {0x00, 0x00, 0x01, 0x0A}; -const uint8_t stat2[] = {0x00, 0x00, 0x01, 0x08}; -const uint8_t stat3[] = {0x00, 0x00, 0x01, 0x0D}; -const uint8_t stat4[] = {0x00, 0x00, 0x01, 0x0C}; - -// broadcast -const uint8_t lan_stat1[] = {0x00, 0x01, 0x0A}; -const uint8_t lan_reg[] = {SW_ID, 0x01, 0x00}; -const uint8_t lan_init[] = {SW_ID, 0x01, 0x01}; -const uint8_t lan_check[] = {SW_ID, 0x01, 0x20}; -const uint8_t lan_playit[] = {SW_ID, 0x01, 0x45, 0x63}; - -const uint8_t play_req1[] = {0x00, 0x25, 0x63, 0x80}; - -#ifdef __AVENSIS__ -const uint8_t play_req2[] = {0x00, SW_ID, 0x63, 0x42}; -#else -const uint8_t play_req2[] = {0x00, SW_ID, 0x63, 0x42, 0x01, 0x00}; -#endif - -const uint8_t play_req3[] = {0x00, SW_ID, 0x63, 0x42, 0x41}; -const uint8_t stop_req[] = {0x00, SW_ID, 0x63, 0x43, 0x01}; -const uint8_t stop_req2[] = {0x00, SW_ID, 0x63, 0x43, 0x41}; - // answers -const AVCLAN_KnownMessage_t CMD_REGISTER = { - UNICAST, 5, {0x00, 0x01, SW_ID, 0x10, 0x63}}; -const AVCLAN_KnownMessage_t CMD_STATUS1 = { - UNICAST, 4, {0x00, 0x01, 0x00, 0x1A}}; -const AVCLAN_KnownMessage_t CMD_STATUS2 = { - UNICAST, 4, {0x00, 0x01, 0x00, 0x18}}; -const AVCLAN_KnownMessage_t CMD_STATUS3 = { - UNICAST, 4, {0x00, 0x01, 0x00, 0x1D}}; -const AVCLAN_KnownMessage_t CMD_STATUS4 = { - UNICAST, 5, {0x00, 0x01, 0x00, 0x1C, 0x00}}; -AVCLAN_KnownMessage_t CMD_CHECK = { - UNICAST, 6, {0x00, 0x01, SW_ID, 0x30, 0x00, 0x00}}; +uint8_t lancheck_resp[] = {0x00, 0x01, 0x00, 0xFF}; +const uint8_t list_functions_resp[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, + List_Functions_Resp, dev_CD_CHANGER}; +uint8_t ping_resp[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, Ping_Resp, 0xFF, 0x00}; +uint8_t function_change_resp[] = {0x00, dev_CD_CHANGER, dev_COMM_v1, 0xFF, + 0x01}; +uint8_t cdstatus_resp[] = { + dev_CD_CHANGER, dev_STATUS, Report, 0x01, cd_SEEKING_TRACK, 0x01, 0x00, + 0xFF, 0x7F, 0x00, 0xc0}; -const AVCLAN_KnownMessage_t CMD_STATUS5 = { - UNICAST, 5, {0x00, 0x5C, 0x12, 0x53, 0x02}}; -const AVCLAN_KnownMessage_t CMD_STATUS5A = { - BROADCAST, 5, {0x5C, 0x31, 0xF1, 0x00, 0x00}}; - -const AVCLAN_KnownMessage_t CMD_STATUS6 = { - UNICAST, 6, {0x00, 0x5C, 0x32, 0xF0, 0x02, 0x00}}; - -const AVCLAN_KnownMessage_t CMD_PLAY_OK1 = { - UNICAST, 5, {0x00, 0x63, SW_ID, 0x50, 0x01}}; -const AVCLAN_KnownMessage_t CMD_PLAY_OK2 = { - UNICAST, 5, {0x00, 0x63, SW_ID, 0x52, 0x01}}; -const AVCLAN_KnownMessage_t CMD_PLAY_OK3 = { - BROADCAST, - 11, - {0x63, 0x31, 0xF1, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x80}}; -AVCLAN_KnownMessage_t CMD_PLAY_OK4 = { - BROADCAST, - 11, - {0x63, 0x31, 0xF1, 0x01, 0x28, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80}}; - -const AVCLAN_KnownMessage_t CMD_STOP1 = { - UNICAST, 5, {0x00, 0x63, SW_ID, 0x53, 0x01}}; -AVCLAN_KnownMessage_t CMD_STOP2 = { - BROADCAST, - 11, - {0x63, 0x31, 0xF1, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80}}; - -const AVCLAN_KnownMessage_t CMD_BEEP = { - UNICAST, 5, {0x00, 0x63, 0x29, 0x60, 0x02}}; - -uint8_t CheckCmd(const AVCLAN_frame_t *frame, const uint8_t *cmd, uint8_t l); +uint8_t AVCLAN_handleframe(const AVCLAN_frame_t *frame); +void AVCLAN_updateCDStatus(); void AVCLAN_init() { // Pull-ups are disabled by default @@ -274,16 +217,17 @@ void AVCLAN_init() { cd_status.disc = 1; cd_status.cd2 = cd_status.cd3 = cd_status.cd4 = cd_status.cd5 = cd_status.cd6 = 0; - cd_status.state = cd_LOADING; + cd_status.state = cd_SEEKING_TRACK; cd_status.disk_random = 0; cd_status.random = 0; cd_status.disk_repeat = 0; cd_status.repeat = 0; cd_status.scan = 0; + cd_status.flags2 = 0xC0; cd_status.track = 1; - cd_status.mins = 0; - cd_status.secs = 0; + cd_status.mins = 0xFF; + cd_status.secs = 0x7F; cd_Track = &cd_status.track; cd_Time_Min = &cd_status.mins; @@ -707,74 +651,8 @@ uint8_t AVCLAN_readframe() { if (printAllFrames) AVCLAN_printframe(&frame, printBinary); - if (!AVCLAN_ismuted()) { - if (shouldACK) { - if (CheckCmd(&frame, stat1, sizeof(stat1))) { - answerReq = cm_Status1; - return 1; - } - if (CheckCmd(&frame, stat2, sizeof(stat2))) { - answerReq = cm_Status2; - return 1; - } - if (CheckCmd(&frame, stat3, sizeof(stat3))) { - answerReq = cm_Status3; - return 1; - } - if (CheckCmd(&frame, stat4, sizeof(stat4))) { - answerReq = cm_Status4; - return 1; - } - // if (CheckCmd((uint8_t*)stat5)) { - // answerReq = cm_Status5; - // return 1; - // } - - if (CheckCmd(&frame, play_req1, sizeof(play_req1))) { - answerReq = cm_PlayReq1; - return 1; - } - if (CheckCmd(&frame, play_req2, sizeof(play_req2))) { - answerReq = cm_PlayReq2; - return 1; - } - if (CheckCmd(&frame, play_req3, sizeof(play_req3))) { - answerReq = cm_PlayReq3; - return 1; - } - if (CheckCmd(&frame, stop_req, sizeof(stop_req))) { - answerReq = cm_StopReq; - return 1; - } - if (CheckCmd(&frame, stop_req2, sizeof(stop_req2))) { - answerReq = cm_StopReq2; - return 1; - } - } else { // broadcast check - - if (CheckCmd(&frame, lan_playit, sizeof(lan_playit))) { - answerReq = cm_PlayIt; - return 1; - } - if (CheckCmd(&frame, lan_check, sizeof(lan_check))) { - answerReq = cm_Check; - CMD_CHECK.data[4] = frame.data[3]; - return 1; - } - if (CheckCmd(&frame, lan_reg, sizeof(lan_reg))) { - answerReq = cm_Register; - return 1; - } - if (CheckCmd(&frame, lan_init, sizeof(lan_init))) { - answerReq = cm_Init; - return 1; - } - if (CheckCmd(&frame, lan_stat1, sizeof(lan_stat1))) { - answerReq = cm_Status1; - return 1; - } - } - } + if (!AVCLAN_ismuted()) + AVCLAN_handleframe(&frame); answerReq = cm_Null; return 1; @@ -786,10 +664,9 @@ uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame) { STOPEvent; - // wait for free line - uint8_t line_busy = 1; uint8_t parity = 0; + // wait for free line TCB1.CNT = 0; while (BUS_IS_IDLE) { // Wait for 120% of a bit length @@ -876,114 +753,211 @@ uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame) { return 0; } -uint8_t AVCLAN_responseNeeded() { return (answerReq != 0); } +const AVCLAN_frame_t *frameQueue[4]; + +static inline uint8_t qFull() { + return ((qWrite - qRead) == sizeof(frameQueue)); +} + +static inline uint8_t qMask(uint8_t pos) { + return pos & (sizeof(frameQueue) - 1); +} + +uint8_t qPush(const AVCLAN_frame_t *frame) { + if (qFull()) + return 1; + + frameQueue[qMask(qWrite++)] = frame; + + return 0; +} + +const AVCLAN_frame_t *qPeek() { + if (qEmpty()) + return NULL; + + return frameQueue[qMask(qRead)]; +} + +const AVCLAN_frame_t *qPop() { + if (qEmpty()) + return NULL; + + return frameQueue[qMask(qRead++)]; +} + +uint8_t AVCLAN_handleframe(const AVCLAN_frame_t *frame) { + uint8_t respond = 0; + AVCLAN_frame_t *resp = malloc(sizeof(AVCLAN_frame_t)); + + if (!resp) + return NULL; + + resp->controller_addr = DEVICE_ADDR; + resp->control = 0xF; + + if (!frame->broadcast) { + // peripheral_addr will be 0xFFF or 0x1FF based on all currently known + // examples + // if (frame->peripheral_addr == 0xFFF || frame->peripheral_addr == 0x1FF) { + if (frame->data[0] == 0) { + if (frame->data[1] == dev_COMM_CTRL) { + switch (frame->data[2]) { + case Lancheck_Scan_Req: + lancheck_resp[3] = Lancheck_Scan_Resp; + goto GROUPED; + case Lancheck_Req: + lancheck_resp[3] = Lancheck_Resp; + goto GROUPED; + case Lancheck_End_Req: + lancheck_resp[3] = Lancheck_End_Resp; + goto GROUPED; + default: + break; + GROUPED: + resp->broadcast = UNICAST; + resp->peripheral_addr = HU_ADDR; + resp->length = sizeof(lancheck_resp); + resp->data = (uint8_t *)lancheck_resp; + respond = 1; + } + } + } else if (frame->data[0] == dev_COMM_v1) { + if (frame->data[1] == dev_COMM_CTRL) { + switch (frame->data[2]) { + case Advertise_Function: + if (frame->data[3] == dev_CD_CHANGER) + CD_Mode = stPlay; + else + CD_Mode = stStop; + break; + case Ping_Req: + resp->broadcast = UNICAST; + resp->peripheral_addr = HU_ADDR; + resp->length = sizeof(ping_resp); + ping_resp[4] = frame->data[3]; + resp->data = (uint8_t *)&ping_resp; + respond = 1; + break; + case List_Functions_Req: + resp->broadcast = UNICAST; + resp->peripheral_addr = HU_ADDR; + resp->length = sizeof(list_functions_resp); + resp->data = (uint8_t *)&list_functions_resp; + respond = 1; + break; + // case Restart_Lan: + // break; + default: + } + } + } + // } + } else if (frame->peripheral_addr == DEVICE_ADDR) { // unicast to CD changer + if (frame->data[0] == 0) { + switch (frame->data[1]) { + case dev_COMM_v1: + switch (frame->data[2]) { + case dev_CD_CHANGER: + switch (frame->data[3]) { + case Enable_Function_Req: + function_change_resp[3] = Enable_Function_Resp; + cd_status.state = cd_SEEKING; + cd_status.flags2 = 0x80; + *cd_Time_Min = 0x00; + *cd_Time_Sec = 0x00; + CD_Mode = stPlay; + answerReq = cm_CDStatus; + goto GROUPED2; + case Disable_Function_Req: + function_change_resp[3] = Disable_Function_Resp; + CD_Mode = stStop; + cd_status.state = 0; + *cd_Time_Min = 0x00; + *cd_Time_Sec = 0x00; + answerReq = cm_CDStatus; + goto GROUPED2; + // case 0x80: + // act = Inserted_CD; + // goto GROUPED; + default: + break; + GROUPED2: + resp->broadcast = UNICAST; + resp->peripheral_addr = HU_ADDR; + resp->length = sizeof(function_change_resp); + resp->data = (uint8_t *)function_change_resp; + respond = 1; + } + default: + } + break; + case dev_CMD_SW: + case dev_STATUS: + if (frame->data[2] == dev_CD_CHANGER) { + switch (frame->data[3]) { + case Request_Report: + cdstatus_resp[2] = Report; + goto GROUPED3; + case Request_Report2: + cdstatus_resp[2] = Report2; + goto GROUPED3; + case Request_Loader2: + cdstatus_resp[2] = Report_Loader2; + goto GROUPED3; + default: + break; + GROUPED3: + memcpy(&cdstatus_resp[3], &cd_status, sizeof(cd_status)); + resp->broadcast = BROADCAST; + resp->peripheral_addr = 0x1FF; + resp->length = sizeof(function_change_resp); + resp->data = (uint8_t *)function_change_resp; + respond = 1; + } + } + break; + default: + } + } + } + + if (!respond) { + free(resp); + } else { + qPush(resp); + } + + return respond; +} uint8_t AVCLAN_respond() { uint8_t r = 0; - AVCLAN_frame_t frame = {.broadcast = UNICAST, - .controller_addr = CD_ID, - .peripheral_addr = HU_ID, - .control = 0xF, - .length = 0}; - - switch (answerReq) { - case cm_Status1: - frame.broadcast = CMD_STATUS1.broadcast; - frame.length = CMD_STATUS1.length; - frame.data = (uint8_t *)&CMD_STATUS1.data[0]; - r = AVCLAN_sendframe(&frame); - break; - case cm_Status2: - frame.broadcast = CMD_STATUS2.broadcast; - frame.length = CMD_STATUS2.length; - frame.data = (uint8_t *)&CMD_STATUS2.data[0]; - r = AVCLAN_sendframe(&frame); - break; - case cm_Status3: - frame.broadcast = CMD_STATUS3.broadcast; - frame.length = CMD_STATUS3.length; - frame.data = (uint8_t *)&CMD_STATUS3.data[0]; - r = AVCLAN_sendframe(&frame); - break; - case cm_Status4: - frame.broadcast = CMD_STATUS4.broadcast; - frame.length = CMD_STATUS4.length; - frame.data = (uint8_t *)&CMD_STATUS4.data[0]; - r = AVCLAN_sendframe(&frame); - break; - case cm_Register: - frame.broadcast = CMD_REGISTER.broadcast; - frame.length = CMD_REGISTER.length; - frame.data = (uint8_t *)&CMD_REGISTER.data[0]; - r = AVCLAN_sendframe(&frame); - break; - // case cm_Init: // RS232_Print("INIT\n"); - // r = AVCLan_SendInitCommands(); - // break; - case cm_Check: - frame.broadcast = CMD_CHECK.broadcast; - frame.length = CMD_CHECK.length; - frame.data = CMD_CHECK.data; - r = AVCLAN_sendframe(&frame); - CMD_CHECK.data[6]++; - RS232_Print("AVCCHK\n"); - break; - case cm_PlayReq1: - frame.broadcast = CMD_PLAY_OK1.broadcast; - frame.length = CMD_PLAY_OK1.length; - frame.data = (uint8_t *)&CMD_PLAY_OK1.data; - r = AVCLAN_sendframe(&frame); - break; - case cm_PlayReq2: - case cm_PlayReq3: - frame.broadcast = CMD_PLAY_OK2.broadcast; - frame.length = CMD_PLAY_OK2.length; - frame.data = (uint8_t *)&CMD_PLAY_OK2.data; - r = AVCLAN_sendframe(&frame); - if (!r) { - frame.broadcast = CMD_PLAY_OK3.broadcast; - frame.length = CMD_PLAY_OK3.length; - frame.data = (uint8_t *)&CMD_PLAY_OK3.data; - r = AVCLAN_sendframe(&frame); + if (!qEmpty()) { + const AVCLAN_frame_t *resp = qPeek(); + for (uint8_t i = 0; i < MAX_SEND_ATTEMPTS; i++) { + r = AVCLAN_sendframe(resp); + if (!r) { // Send succeeded + resp = qPop(); + free((AVCLAN_frame_t *)resp); + break; } - CD_Mode = stPlay; - break; - case cm_PlayIt: - RS232_Print("PLAY\n"); - frame.broadcast = CMD_PLAY_OK4.broadcast; - frame.length = CMD_PLAY_OK4.length; - frame.data = (uint8_t *)&CMD_PLAY_OK4.data; - CMD_PLAY_OK4.data[8] = *cd_Track; - CMD_PLAY_OK4.data[9] = *cd_Time_Min; - CMD_PLAY_OK4.data[10] = *cd_Time_Sec; - r = AVCLAN_sendframe(&frame); - CD_Mode = stPlay; - case cm_CDStatus: - if (!r) - AVCLan_Send_Status(); - break; - case cm_StopReq: - case cm_StopReq2: - CD_Mode = stStop; - frame.broadcast = CMD_STOP1.broadcast; - frame.length = CMD_STOP1.length; - frame.data = (uint8_t *)&CMD_STOP1.data; - r = AVCLAN_sendframe(&frame); + } + if (r) { // Sending failed all attempts; give up sending frame + resp = qPop(); + free((AVCLAN_frame_t *)resp); + } + } else if (!answerReq) { + AVCLAN_frame_t frame = {.broadcast = UNICAST, + .controller_addr = DEVICE_ADDR, + .peripheral_addr = HU_ADDR, + .control = 0xF, + .length = 0}; - CMD_STOP2.data[8] = *cd_Track; - CMD_STOP2.data[9] = *cd_Time_Min; - CMD_STOP2.data[10] = *cd_Time_Sec; - frame.broadcast = CMD_STOP2.broadcast; - frame.length = CMD_STOP2.length; - frame.data = (uint8_t *)&CMD_STOP2.data; - r = AVCLAN_sendframe(&frame); - break; - case cm_Beep: - frame.broadcast = CMD_BEEP.broadcast; - frame.length = CMD_BEEP.length; - frame.data = (uint8_t *)&CMD_BEEP.data; - r = AVCLAN_sendframe(&frame); - break; + switch (answerReq) { + case cm_CDStatus: + AVCLAN_updateCDStatus(); + } } answerReq = cm_Null; @@ -1070,45 +1044,27 @@ AVCLAN_frame_t *AVCLAN_parseframe(const uint8_t *bytes, uint8_t len) { return frame; } -uint8_t CheckCmd(const AVCLAN_frame_t *frame, const uint8_t *cmd, uint8_t l) { - for (uint8_t i = 0; i < l; i++) { - if (frame->data[i] != *cmd++) - return 0; +void AVCLAN_updateCDStatus() { + if (CD_Mode) { + if (cd_status.state != cd_PLAYBACK) { + cd_status.state = cd_PLAYBACK; + answerReq = cm_CDStatus; + } + + if (answerReq == cm_CDStatus) { + cdstatus_resp[2] = Report; + memcpy(&cdstatus_resp[3], &cd_status, sizeof(cd_status)); + + AVCLAN_frame_t status = {.broadcast = BROADCAST, + .controller_addr = DEVICE_ADDR, + .peripheral_addr = 0x1FF, + .control = 0xF, + .length = sizeof(cdstatus_resp), + .data = (uint8_t *)&cdstatus_resp}; + + AVCLAN_sendframe(&status); + } } - return 1; -} - -void AVCLan_Send_Status() { - uint8_t STATUS[] = {0x63, 0x31, 0xF1, 0x01, 0x10, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x80}; - STATUS[6] = *cd_Track; - STATUS[7] = *cd_Time_Min; - STATUS[8] = *cd_Time_Sec; - STATUS[9] = 0; - - AVCLAN_frame_t status = {.broadcast = UNICAST, - .controller_addr = CD_ID, - .peripheral_addr = HU_ID, - .control = 0xF, - .length = 11, - .data = &STATUS[0]}; - - AVCLAN_sendframe(&status); -} - -void AVCLan_Register() { - AVCLAN_frame_t register_frame = {.broadcast = CMD_REGISTER.broadcast, - .controller_addr = CD_ID, - .peripheral_addr = HU_ID, - .control = 0xF, - .length = CMD_REGISTER.length, - .data = (uint8_t *)CMD_REGISTER.data}; - RS232_Print("REG_ST\n"); - AVCLAN_sendframe(®ister_frame); - RS232_Print("REG_END\n"); - // AVCLan_Command( cm_Register ); - answerReq = cm_Init; - AVCLAN_respond(); } #ifdef SOFTWARE_DEBUG diff --git a/src/avclandrv.h b/src/avclandrv.h index 8edcf17..f80687b 100644 --- a/src/avclandrv.h +++ b/src/avclandrv.h @@ -49,29 +49,85 @@ extern uint8_t printBinary; typedef enum { cm_Null = 0, - cm_Status1 = 1, - cm_Status2 = 2, - cm_Status3 = 3, - cm_Status4 = 4, - cm_PlayReq1 = 5, - cm_PlayReq2 = 6, - cm_PlayReq3 = 7, - cm_StopReq = 8, - cm_StopReq2 = 9, - cm_Register = 100, - cm_Init = 101, - cm_Check = 102, - cm_PlayIt = 103, - cm_Beep = 110, - cm_NextTrack = 120, - cm_PrevTrack = 121, - cm_NextDisc = 122, - cm_PrevDisc = 123, - cm_ScanModeOn = 130, - cm_ScanModeOff = 131, cm_CDStatus, } commands; +typedef enum { + dev_COMM_CTRL = 0x01, + dev_COMM_v1 = 0x11, + dev_COMM_v2 = 0x12, + dev_SW = 0x21, + dev_SW_NAME = 0x23, + dev_SW_CONVERTING = 0x24, + dev_CMD_SW = 0x25, + dev_STATUS = 0x31, + dev_BEEP_HU = 0x28, + dev_BEEP_SPEAKERS = 0x29, + dev_TUNER = 0x60, + dev_TAPE_DECK = 0x61, + dev_CD = 0x62, + dev_CD_CHANGER = 0x63, + dev_AUDIO_AMP = 0x74, +} devices; + +typedef enum { + // LAN related + List_Functions_Req = 0x00, + List_Functions_Resp = 0x10, + Restart_Lan = 0x01, + Lancheck_End_Req = 0x08, + Lancheck_End_Resp = 0x18, + Lancheck_Scan_Req = 0x0a, + Lancheck_Scan_Resp = 0x1a, + Lancheck_Req = 0x0c, + Lancheck_Resp = 0x1c, + Ping_Req = 0x20, + Ping_Resp = 0x30, + + // Device switching + Enable_Function_Req = 0x42, + Enable_Function_Resp = 0x52, + Disable_Function_Req = 0x43, + Disable_Function_Resp = 0x53, + + Advertise_Function = 0x45, + General_Query = 0x46, + + // Physical interface + Eject = 0x80, + Disc_Up = 0x90, + Disc_Down = 0x91, + Pwrvol_Knob_Righthand_Turn = 0x9c, + Pwrvol_Knob_Lefthand_Turn = 0x9d, + Track_Seek_Up = 0x94, + Track_Seek_Down = 0x95, + CD_Enable_Scan = 0xa6, + CD_Disable_Scan = 0xa7, + CD_Enable_Repeat = 0xa0, + CD_Disable_Repeat = 0xa1, + CD_Enable_Random = 0xb0, + CD_Disable_Random = 0xb1, + + // CD functions + // Events + Inserted_CD = 0x50, + Removed_CD = 0x51, + + // Requests + Request_Report = 0xe0, + Request_Report2 = 0xe2, + Request_Loader2 = 0xe4, + Request_Track_Name = 0xed, + + // Reports + Report = 0xf1, + Report2 = 0xf2, + Report_Loader = 0xf3, + Report_Loader2 = 0xf4, + Report_TOC = 0xf9, + Report_Track_Name = 0xfd, +} actions; + typedef enum { cd_OPEN = 0x01, cd_ERR1 = 0x02, @@ -89,7 +145,7 @@ typedef struct AVCLAN_CD_Status { _Bool cd5 : 1; _Bool cd6 : 1; int : 2; - cd_state state; + uint8_t state; uint8_t disc; uint8_t track; uint8_t mins; @@ -101,7 +157,7 @@ typedef struct AVCLAN_CD_Status { _Bool repeat : 1; _Bool disk_scan : 1; _Bool scan : 1; - int : 2; + int : 1; uint8_t flags2; } AVCLAN_CD_Status_t; @@ -109,12 +165,6 @@ typedef enum { stStop = 0, stPlay = 1 } cd_modes; typedef enum MSG_TYPE { BROADCAST = 0, UNICAST = 1 } MSG_TYPE_t; -typedef struct AVCLAN_KnownMessage_struct { - MSG_TYPE_t broadcast; - uint8_t length; - uint8_t data[11]; -} AVCLAN_KnownMessage_t; - typedef struct AVCLAN_frame_struct { MSG_TYPE_t broadcast; // 0 for broadcast messages uint16_t controller_addr; // formerly "master" @@ -130,7 +180,21 @@ void AVCLAN_muteDevice(uint8_t mute); uint8_t AVCLAN_readframe(); uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame); -uint8_t AVCLAN_responseNeeded(); +// To allow inlining qEmpty and AVCLAN_responseNeeded +#ifndef VAR_DECLS + #define _DECL extern + #define _INIT(x) +#else + #define _DECL + #define _INIT(x) = x +#endif +_DECL uint8_t answerReq _INIT(0); +_DECL uint8_t qWrite _INIT(0); +_DECL uint8_t qRead _INIT(0); + +inline uint8_t qEmpty() { return (qWrite == qRead); } +inline uint8_t AVCLAN_responseNeeded() { return (answerReq != 0) || !qEmpty(); } + uint8_t AVCLAN_respond(); void AVCLAN_printframe(const AVCLAN_frame_t *frame, uint8_t binary); diff --git a/src/sniffer.c b/src/sniffer.c index 8e24fc5..03e8632 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -62,10 +62,8 @@ int main() { if (!BUS_IS_IDLE) { AVCLAN_readframe(); - } else { - // check command from HU - if (AVCLAN_responseNeeded()) - AVCLAN_respond(); + } else if (AVCLAN_responseNeeded()) { + AVCLAN_respond(); } // Key handler