From 8b7701ed93ac19ac386c4de460e1c3424a260262 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Mon, 27 Oct 2025 16:49:02 -0400 Subject: handle ID Control frames (wip) --- fw/eeprom.c | 5 ++-- fw/main.c | 60 +++++++++++++++++++++++--------------- fw/tests/system/can_echo_systest.c | 48 +++++++++++++++--------------- fw/tests/system/can_tx_systest.c | 2 +- 4 files changed, 65 insertions(+), 50 deletions(-) (limited to 'fw') diff --git a/fw/eeprom.c b/fw/eeprom.c index 11d0493..1754885 100644 --- a/fw/eeprom.c +++ b/fw/eeprom.c @@ -177,13 +177,14 @@ eepromWriteCanId(U16 addr, const CanId *id) { U8 buf[4u]; // Copy ID to buffer - memset(buf, 0u, sizeof(buf)); if (id->isExt) { // extended memmove(buf, id->eid, sizeof(buf)); - buf[3u] = (buf[3u] & 0x1F) | 0x80; // set EID flag + buf[3u] = (buf[3u] & 0x1F) | 0x80; // set EID flag: bit 31 } else { // standard buf[0u] = id->sid.lo; buf[1u] = id->sid.hi & 0x7; + buf[2u] = 0u; + buf[3u] = 0u; } return eepromWrite(addr, buf, sizeof(buf)); diff --git a/fw/main.c b/fw/main.c index d5b1443..81db05d 100644 --- a/fw/main.c +++ b/fw/main.c @@ -43,12 +43,10 @@ static const CanId idCtrlFilter = { }; // Receive buffer 0 mask. -// RXB0 is used for control messages for reading/writing calibration tables -// and CAN IDs for each parameter. -// This mask is the union of the two control message filters. +// RXB0 receives Table and ID Control Frames. static const CanId rxb0Mask = { .isExt = true, - .eid = {0x00, 0x21, 0x27, 0x01}, // 1272100h + .eid = {0x00, 0xFF, 0xFF, 0x1F}, // all but LSB }; // Receive buffer 1 mask. @@ -96,13 +94,13 @@ loadParamIds(void) { for (k = 0u; k < NPARAM; k++) { status = eepromReadCanId(paramIdAddrs[k], (CanId*)¶mIds[k]); if (status != OK) { + INTCONbits.GIE = oldGie; // restore previous interrupt setting return FAIL; } } // Restore previous interrupt setting INTCONbits.GIE = oldGie; - return OK; } @@ -134,10 +132,11 @@ main(void) { canSetFilter0(&tblCtrlFilter); // Table Control Frames canSetFilter1(&idCtrlFilter); // ID Control Frames canSetMask1(&rxb1Mask); // RXB1 receives parameter values - // Permissive RXB1 mask; filter frames in software + // RXB1 messages are filtered in software + canIE(true); // enable interrupts on MCP2515's INT pin + canSetMode(CAN_MODE_NORMAL); // Enable interrupts - canIE(true); // enable interrupts on MCP2515's INT pin INTCON = 0x00; // clear flags OPTION_REGbits.INTEDG = 0; // interrupt on falling edge of INT pin INTCONbits.INTE = 1; // enable INT pin @@ -161,16 +160,12 @@ handleTblCtrlFrame(const CanFrame *frame) { // of the requested parameter. static Status respondIdCtrl(Param param) { - CanFrame response; CanId paramId; - Status status; + CanFrame response; - // Read parameter's CAN ID from EEPROM + // Get parameter's CAN ID if ((U8)param < NPARAM) { - status = eepromReadCanId(paramIdAddrs[param], ¶mId); - if (status != OK) { - return FAIL; // read failed - } + paramId = paramIds[param]; } else { return FAIL; // invalid parameter } @@ -221,20 +216,22 @@ setParamId(const CanFrame *frame) { return FAIL; // invalid DLC } - // Extract param # from Control Frame's ID + // Set param's ID param = frame->id.eid[0u] & 0xF; - if ((U8)param >= NPARAM) { + if ((U8)param < NPARAM) { + // Update copy in EEPROM + status = eepromWriteCanId(paramIdAddrs[param], ¶mId); + if (status != OK) { + return FAIL; // write failed + } + // Update copy in RAM + paramIds[param] = paramId; + } else { return FAIL; // invalid parameter } - // Update copy in EEPROM - status = eepromWriteCanId(paramIdAddrs[param], ¶mId); - if (status != OK) { - return FAIL; // write failed - } - - // Update copy in PIC's RAM - paramIds[param] = paramId; + // TODO: remove + respondIdCtrl(param); // echo return OK; } @@ -253,10 +250,25 @@ handleIdCtrlFrame(const CanFrame *frame) { } } +// TODO: remove +static void +echo(const CanFrame *frame) { + CanFrame out; + U8 k; + + memmove(&out, frame, sizeof(*frame)); + out.rtr = false; + for (k = 0u; k < out.dlc; k++) { + out.data[k]++; + } + canTx(&out); +} + // Handle a frame potentially holding a parameter value. static Status handleParamFrame(const CanFrame *frame) { // TODO + echo(frame); } void diff --git a/fw/tests/system/can_echo_systest.c b/fw/tests/system/can_echo_systest.c index 798e45f..f0e08d2 100644 --- a/fw/tests/system/can_echo_systest.c +++ b/fw/tests/system/can_echo_systest.c @@ -1,4 +1,4 @@ -/* Listen for a standard DATA FRAME with ID 123h; +/* Listen for a frame with ID 123h or 1234567h; * echo it back with each byte of the DATA FIELD incremented by 1. */ @@ -12,6 +12,19 @@ #include "spi.h" #include "can.h" +static const CanId mask0 = { + .isExt = true, + .eid = {0xFF, 0xFF, 0xFF, 0x1F}}; +static const CanId filter0 = { + .isExt = true, + .eid = {0x67, 0x45, 0x23, 0x01}}; // 1234567h +static const CanId mask1 = { + .isExt = false, + .sid = {.lo = 0xFF, .hi = 0x7}}; +static const CanId filter2 = { + .isExt = false, + .sid = {.lo = 0x23, .hi = 0x1}}; // 123h + void main(void) { sysInit(); @@ -20,20 +33,11 @@ main(void) { // Setup MCP2515 CAN controller canSetBitTiming(CAN_TIMING_10K); - CanId id = { - .type=CAN_ID_STD, - .sid = {0xFF, 0xFF}, - }; - canSetMask0(&id); // set masks - canSetMask1(&id); - canSetFilter1(&id); // set unused filters - canSetFilter2(&id); - canSetFilter3(&id); - canSetFilter4(&id); - canSetFilter5(&id); - id.sid = (U16){0x01, 0x23}; // listen for message on filter 0 - canSetFilter0(&id); - canIE(true); // enable interrupts on INT pin + canSetMask0(&mask0); // RXB0 + canSetFilter0(&filter0); + canSetMask1(&mask1); // RXB1 + canSetFilter2(&filter2); + canIE(true); // enable interrupts on MCP2515's INT pin canSetMode(CAN_MODE_NORMAL); // Enable interrupts @@ -62,24 +66,22 @@ echo(CanFrame *frame) { void __interrupt() isr(void) { - U8 status; CanFrame frame; if (INTCONbits.INTF) { - status = canRxStatus(); - switch (status & 0x7) { // check filter match + switch (canRxStatus() & 0x7) { // check filter match case 0u: // RXF0 canReadRxb0(&frame); echo(&frame); break; - case 1u: // RXF1 - canReadRxb0(&frame); // clear interrupt flag + case 2u: // RXF2 + canReadRxb1(&frame); + echo(&frame); break; default: - // Message in RXB1 - canReadRxb1(&frame); // clear interrupt flag + canReadRxb0(&frame); // clear interrupt flag + canReadRxb1(&frame); } - INTCONbits.INTF = 0; } } diff --git a/fw/tests/system/can_tx_systest.c b/fw/tests/system/can_tx_systest.c index ef1d7b0..f6651c6 100644 --- a/fw/tests/system/can_tx_systest.c +++ b/fw/tests/system/can_tx_systest.c @@ -13,7 +13,7 @@ // Frame to transmit periodically static const CanFrame frame = { .id = { - .type = CAN_ID_STD, + .isExt = false, .sid = {0x01, 0x23}, }, .rtr = false, -- cgit v1.2.3