Correctly respond to button actions (CMD_SW state report)

This commit is contained in:
Allen Hill
2026-06-15 15:04:47 -07:00
parent 09782495ab
commit 60d39c1c2f
3 changed files with 61 additions and 101 deletions
+59 -99
View File
@@ -148,24 +148,6 @@ static const uint8_t ping_resp[] = {0x00, dev_COMM_CTRL, dev_COMM_v1,
static const uint8_t function_change_resp[] = {0x00, dev_CD_CHANGER, static const uint8_t function_change_resp[] = {0x00, dev_CD_CHANGER,
dev_COMM_v1, 0xFF, 0x01}; dev_COMM_v1, 0xFF, 0x01};
#define STATUS_REPORT_DATA \
{dev_CD_CHANGER, \
dev_STATUS, \
Status_Report, \
0x01, \
cd_SEEKING_TRACK, \
0x01, \
0x00, \
0xFF, \
0x7F, \
0x00, \
0x80}
static const uint8_t cdstatus_resp[] = STATUS_REPORT_DATA;
static_assert(sizeof(AVCLAN_CD_Status_t) + 3 == sizeof(cdstatus_resp),
"canned Status Report message doesn't match size of CD status "
"plus header bytes");
// No knowledge/understanding of field meaning/interpretation // No knowledge/understanding of field meaning/interpretation
static const uint8_t cdinitreport_resp[] = { static const uint8_t cdinitreport_resp[] = {
dev_CD_CHANGER, dev_STATUS, Initial_Report_Response, 0x01, 0x31, 0x10, dev_CD_CHANGER, dev_STATUS, Initial_Report_Response, 0x01, 0x31, 0x10,
@@ -953,7 +935,7 @@ response_t AVCLAN_handleframe(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) {
cd_status.secs = 0; cd_status.secs = 0;
cd_status.state = cd_SEEKING | cd_SEEKING_TRACK; cd_status.state = cd_SEEKING | cd_SEEKING_TRACK;
cd_status.flags2 = 0xc0; cd_status.flags2 = 0xc0;
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_STATUS);
AVCLAN_startPlaying(); AVCLAN_startPlaying();
respond = r_NormalizeState; respond = r_NormalizeState;
} }
@@ -1011,8 +993,7 @@ response_t AVCLAN_handleframe(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) {
// triggering (after {0x00, dev_CD_CHANGER, dev_COMM_v1, Insertion, // triggering (after {0x00, dev_CD_CHANGER, dev_COMM_v1, Insertion,
// 0x01} response) proper activation of mockingboard/cd-changer. // 0x01} response) proper activation of mockingboard/cd-changer.
// - Subsequently observed when pressing (technically // - Subsequently observed when pressing (technically
// releasing?) the fast-forward button (and not rewind? needs // releasing?) the fast-forward button and rewind
// confirmation)
out->is_unicast = true; out->is_unicast = true;
out->peripheral_addr = HU_ADDR; out->peripheral_addr = HU_ADDR;
{ {
@@ -1065,9 +1046,8 @@ response_t AVCLAN_handleframe(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) {
*cd_Track = 1; *cd_Track = 1;
*cd_Time_Min = 0xff; *cd_Time_Min = 0xff;
*cd_Time_Sec = 0x7f; *cd_Time_Sec = 0x7f;
cd_status.flags |= cd_SCAN;
cd_status.flags2 = 0xc0; cd_status.flags2 = 0xc0;
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_CMD_SW);
respond = r_TrackChange; respond = r_TrackChange;
break; break;
case PACK3(dev_CMD_SW, dev_CD_CHANGER, Track_Seek_Down): case PACK3(dev_CMD_SW, dev_CD_CHANGER, Track_Seek_Down):
@@ -1082,74 +1062,49 @@ response_t AVCLAN_handleframe(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) {
*cd_Time_Min = 0xff; *cd_Time_Min = 0xff;
*cd_Time_Sec = 0x7f; *cd_Time_Sec = 0x7f;
cd_status.flags2 = 0xc0; cd_status.flags2 = 0xc0;
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_CMD_SW);
respond = r_TrackChange; respond = r_TrackChange;
break; break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Random): case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Random):
// cd_status.flags |= cd_RANDOM; cd_status.flags |= cd_RANDOM;
// out->is_unicast = true; AVCLAN_generateStatus(out, true, dev_CMD_SW);
// out->peripheral_addr = HU_ADDR; respond = r_StatusReport;
// { break;
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_COMM_v1, case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Random):
// CD_Enable_Random, 0x01}; cd_status.flags &= ~cd_RANDOM;
// out->length = sizeof(msg); AVCLAN_generateStatus(out, true, dev_CMD_SW);
// memcpy(out->data, msg, sizeof(msg)); respond = r_StatusReport;
// } break;
// respond = r_StatusReport; case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Repeat):
// break; cd_status.flags |= cd_REPEAT;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Random): AVCLAN_generateStatus(out, true, dev_CMD_SW);
// cd_status.flags &= ~cd_RANDOM; respond = r_StatusReport;
// AVCLAN_generateStatus(out); break;
// respond = r_Handled; case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Repeat):
// break; cd_status.flags &= ~cd_REPEAT;
case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Repeat): AVCLAN_generateStatus(out, true, dev_CMD_SW);
cd_status.flags |= cd_REPEAT; respond = r_StatusReport;
// out->is_unicast = true; break;
out->is_unicast = false; case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Disk_Random):
out->peripheral_addr = 0x1FF; cd_status.flags |= cd_DISK_RANDOM;
{ AVCLAN_generateStatus(out, true, dev_CMD_SW);
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_CMD_SW, respond = r_StatusReport;
// CD_Enable_Repeat, 0x01}; break;
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_CMD_SW, case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Disk_Random):
// CD_Enable_Repeat, 0x00}; cd_status.flags &= ~cd_DISK_RANDOM;
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_CMD_SW, AVCLAN_generateStatus(out, true, dev_CMD_SW);
// CD_Enable_Repeat}; respond = r_StatusReport;
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_COMM_v1, break;
// CD_Enable_Repeat, 0x01}; case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Disk_Repeat):
// const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_COMM_v1, cd_status.flags |= cd_DISK_REPEAT;
// CD_Enable_Repeat, 0x00}; AVCLAN_generateStatus(out, true, dev_CMD_SW);
const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_COMM_v1, respond = r_StatusReport;
CD_Enable_Repeat}; break;
out->length = sizeof(msg); case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Disk_Repeat):
memcpy(out->data, msg, sizeof(msg)); cd_status.flags &= ~cd_DISK_REPEAT;
} AVCLAN_generateStatus(out, true, dev_CMD_SW);
respond = r_StatusReport; respond = r_StatusReport;
break; break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Repeat):
// cd_status.flags &= ~cd_REPEAT;
// AVCLAN_generateStatus(out);
// respond = r_Handled;
// break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Disk_Random):
// cd_status.flags |= cd_DISK_RANDOM;
// AVCLAN_generateStatus(out);
// respond = r_Handled;
// break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Disk_Random):
// cd_status.flags &= ~cd_DISK_RANDOM;
// AVCLAN_generateStatus(out);
// respond = r_Handled;
// break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Enable_Disk_Repeat):
// cd_status.flags |= cd_DISK_REPEAT;
// AVCLAN_generateStatus(out);
// respond = r_Handled;
// break;
// case PACK3(dev_CMD_SW, dev_CD_CHANGER, CD_Disable_Disk_Repeat):
// cd_status.flags &= ~cd_DISK_REPEAT;
// AVCLAN_generateStatus(out);
// respond = r_Handled;
// break;
} }
} }
@@ -1181,15 +1136,15 @@ RFrame_t *AVCLAN_statemachine(RFrame_t *resp) {
case r_TrackChange: AVCLAN_setTime(0x00, 0x00); [[fallthrough]]; case r_TrackChange: AVCLAN_setTime(0x00, 0x00); [[fallthrough]];
case r_NormalizeState: case r_NormalizeState:
AVCLAN_normalizeState(); AVCLAN_normalizeState();
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_STATUS);
resp->r = r_Handled; resp->r = r_Handled;
break; break;
case r_StartPlaying: case r_StartPlaying:
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_STATUS);
resp->r = r_NormalizeState; resp->r = r_NormalizeState;
break; break;
case r_StatusReport: case r_StatusReport:
AVCLAN_generateStatus(out); AVCLAN_generateStatus(out, true, dev_STATUS);
resp->r = r_Handled; resp->r = r_Handled;
break; break;
case r_Handled: [[fallthrough]]; case r_Handled: [[fallthrough]];
@@ -1315,7 +1270,7 @@ uint8_t AVCLAN_parseframe(const uint8_t *bytes, uint8_t len,
// Only used for regularly scheduled periodic updates // Only used for regularly scheduled periodic updates
AVCLAN_frame_t *AVCLAN_getStatusFrame() { AVCLAN_frame_t *AVCLAN_getStatusFrame() {
static uint8_t status_data[] = STATUS_REPORT_DATA; static uint8_t status_data[sizeof(AVCLAN_CD_Status_t) + 3] = {0};
static AVCLAN_frame_t status = {.is_unicast = false, static AVCLAN_frame_t status = {.is_unicast = false,
.controller_addr = DEVICE_ADDR, .controller_addr = DEVICE_ADDR,
.peripheral_addr = 0x1FF, .peripheral_addr = 0x1FF,
@@ -1327,19 +1282,24 @@ AVCLAN_frame_t *AVCLAN_getStatusFrame() {
} }
// Used for changed status messages // Used for changed status messages
void AVCLAN_generateStatus(AVCLAN_frame_t *status) { void AVCLAN_generateStatus(AVCLAN_frame_t *status, bool is_unicast,
devices to) {
*status = (AVCLAN_frame_t){ *status = (AVCLAN_frame_t){
.is_unicast = false, .is_unicast = is_unicast,
.controller_addr = DEVICE_ADDR, .controller_addr = DEVICE_ADDR,
.peripheral_addr = 0x1FF, .peripheral_addr = (is_unicast) ? HU_ADDR : 0x1FF,
.control = 0xF, .control = 0xF,
.length = sizeof(cdstatus_resp), .length = sizeof(AVCLAN_CD_Status_t) + ((is_unicast) ? 4 : 3),
.data = status->data, // don't overwrite data pointer .data = status->data, // don't overwrite data pointer
}; };
status->data[0] = dev_CD_CHANGER;
status->data[1] = dev_STATUS; uint8_t *data = status->data;
status->data[2] = Status_Report; if (is_unicast)
serializeCDStatus(&status->data[3]); *data++ = 0x00;
*data++ = dev_CD_CHANGER;
*data++ = to;
*data++ = Status_Report;
serializeCDStatus(data);
} }
void AVCLAN_normalizeState() { void AVCLAN_normalizeState() {
+1 -1
View File
@@ -215,7 +215,7 @@ void AVCLAN_printframe(const AVCLAN_frame_t *frame, bool binary);
uint8_t AVCLAN_parseframe(const uint8_t *bytes, uint8_t len, uint8_t AVCLAN_parseframe(const uint8_t *bytes, uint8_t len,
AVCLAN_frame_t *frame); AVCLAN_frame_t *frame);
AVCLAN_frame_t *AVCLAN_getStatusFrame(); AVCLAN_frame_t *AVCLAN_getStatusFrame();
void AVCLAN_generateStatus(AVCLAN_frame_t *status); void AVCLAN_generateStatus(AVCLAN_frame_t *status, bool is_unicast, devices to);
bool AVCLAN_isPlaying(); bool AVCLAN_isPlaying();
void AVCLAN_incrementTime(); void AVCLAN_incrementTime();
+1 -1
View File
@@ -176,7 +176,7 @@ int main() {
} }
} else if (enqueueStatus) { } else if (enqueueStatus) {
AVCLAN_frame_t *status = AVCLAN_getStatusFrame(); AVCLAN_frame_t *status = AVCLAN_getStatusFrame();
AVCLAN_generateStatus(status); AVCLAN_generateStatus(status, true, dev_STATUS);
if (RFrame_t *resp = (RFrame_t *)popQueue(&rcache)) { if (RFrame_t *resp = (RFrame_t *)popQueue(&rcache)) {
*resp = (RFrame_t){.r = r_Handled, .frame = status}; *resp = (RFrame_t){.r = r_Handled, .frame = status};
err = pushQueue(&outgoing, resp); err = pushQueue(&outgoing, resp);