diff options
| -rw-r--r-- | fw/can.c | 28 | ||||
| -rw-r--r-- | fw/dac.c | 14 | ||||
| -rw-r--r-- | fw/eeprom.c | 36 | ||||
| -rw-r--r-- | fw/main.c | 66 | ||||
| -rw-r--r-- | fw/table.c | 21 | ||||
| -rw-r--r-- | fw/table.h | 5 | ||||
| -rw-r--r-- | fw/types.c | 53 | ||||
| -rw-r--r-- | fw/types.h | 43 |
8 files changed, 108 insertions, 158 deletions
@@ -241,14 +241,14 @@ static void packId(CanId *id, U8 sidh, U8 sidl, U8 eid8, U8 eid0) { if (sidl & IDE) { // extended ID id->isExt = true; - id->eid[0u] = eid0; // id[7:0] - id->eid[1u] = eid8; // idi[15:8] - id->eid[2u] = (sidh & 0x7) | (sidl & 0x3) | (sidl >> 3u); // id[23:21], id[20:18], id[17:16] - id->eid[3u] = (sidh >> 3u); // id[28:24] + id->eid = ((U32)eid0 << 0u) // id[7:0] + | ((U32)eid8 << 8u) // id[15:8] + | ((U32)((sidh & 0x7) | (sidl & 0x3) | (sidl >> 3u)) << 16u) // id[23:21], id[20:18], id[17:16] + | ((U32)(sidh >> 3u) << 24u); // id[28:24] } else { // standard ID id->isExt = false; - id->sid.lo = (U8)(sidh << 3u) | (U8)(sidl >> 5u); // sid[7:0] - id->sid.hi = sidh >> 5u; // sid[10:8] + id->sid = ((U16)((sidh << 3u) | (sidl >> 5u)) << 0u) // sid[7:0] + | ((U16)(sidh >> 5u) << 8u); // sid[10:8] } } @@ -296,15 +296,15 @@ canReadRxb1(CanFrame *frame) { static void writeId(const CanId *id, Reg sidh, Reg sidl, Reg eid8, Reg eid0) { if (id->isExt) { // extended - write(eid0, id->eid[0u]); // id[7:0] - write(eid8, id->eid[1u]); // id[15:8] - write(sidl, ((id->eid[2u] << 3u) & 0xE0) | IDE | (id->eid[2u] & 0x3)); // id[20:18], IDE, id[17:16] - write(sidh, (U8)((id->eid[3u] & 0x1F) << 3u) | (id->eid[2u] >> 5u)); // id[28:24], id[23:21] + write(eid0, id->eid & 0xFF); // id[7:0] + write(eid8, (id->eid >> 8u) & 0xFF); // id[15:8] + write(sidl, ((id->eid >> 13u) & 0xE0) | IDE | ((id->eid >> 16u) & 0x03)); // id[20:18], IDE, id[17:16] + write(sidh, (id->eid >> 21u) & 0xFF); // id[28:21] } else { // standard - write(sidh, (U8)(id->sid.hi << 5u) | (U8)(id->sid.lo >> 3u)); - write(sidl, (U8) (id->sid.lo << 5u)); - write(eid8, 0x00); - write(eid0, 0x00); + write(sidh, (id->sid >> 3u) & 0xFF); + write(sidl, (id->sid << 5u) & 0xE0); + write(eid8, 0u); + write(eid0, 0u); } } @@ -11,8 +11,8 @@ // Configuration bits: // buffered, gain=1x, mode=active typedef enum { - CONFA = 0x70, // DAC A - CONFB = 0xF0, // DAC B + CONFA = 0x7000, // DAC A + CONFB = 0xF000, // DAC B } Conf; void @@ -22,7 +22,7 @@ dacInit(void) { DAC1_CS = 1; DAC2_CS = 1; - U16 level = {0u, 0u}; + U16 level = 0u; dacSet1a(level); dacSet1b(level); dacSet2a(level); @@ -31,8 +31,8 @@ dacInit(void) { static void set(U8 dacNum, Conf conf, U16 level) { - level = lshiftU16(level, 2u); // D0 at bit 2 - level.hi = (U8)conf | (level.hi & 0x0F); // set config bits + level <<= 2u; // D0 at bit 2 + level = ((U16)conf & 0xF000) | (level & 0x0FFF); // set config bits if (dacNum == 1u) { DAC1_CS = 0; @@ -41,8 +41,8 @@ set(U8 dacNum, Conf conf, U16 level) { } _delay(1); - (void)spiTx(level.hi); - (void)spiTx(level.lo); + (void)spiTx((level>>8u) & 0xFF); // MSB + (void)spiTx((level>>0u) & 0xFF); // LSB if (dacNum == 1u) { DAC1_CS = 1; diff --git a/fw/eeprom.c b/fw/eeprom.c index 1754885..2cc7807 100644 --- a/fw/eeprom.c +++ b/fw/eeprom.c @@ -2,7 +2,6 @@ #include <stdbool.h> #include <stdint.h> -#include <string.h> #include "system.h" #include "types.h" @@ -88,13 +87,13 @@ waitForWrite(void) { static void spiTxAddr(U16 addr) { - (void)spiTx(addr.hi); - (void)spiTx(addr.lo); + (void)spiTx((addr>>8u) & 0xFF); // MSB + (void)spiTx((addr>>0u) & 0xFF); // LSB } static bool isPageStart(U16 addr) { - return (addr.lo % PAGE_SIZE) == 0; + return (addr % PAGE_SIZE) == 0; } Status @@ -120,7 +119,7 @@ eepromWrite(U16 addr, U8 *data, U8 size) { while (size--) { (void)spiTx(*data); data++; - addr = addU16U8(addr, 1u); + addr++; // Check if write crosses page boundary if (isPageStart(addr) && size) { @@ -178,13 +177,16 @@ eepromWriteCanId(U16 addr, const CanId *id) { // Copy ID to buffer if (id->isExt) { // extended - memmove(buf, id->eid, sizeof(buf)); - buf[3u] = (buf[3u] & 0x1F) | 0x80; // set EID flag: bit 31 + buf[0u] = (id->eid>>0u) & 0xFF; + buf[1u] = (id->eid>>8u) & 0xFF; + buf[2u] = (id->eid>>16u) & 0xFF; + buf[3u] = (id->eid>>24u) & 0x1F; + buf[3u] |= 0x80; // set EID flag in bit 31 } else { // standard - buf[0u] = id->sid.lo; - buf[1u] = id->sid.hi & 0x7; + buf[0u] = (id->sid>>0u) & 0xFF; + buf[1u] = (id->sid>>8u) & 0x07; buf[2u] = 0u; - buf[3u] = 0u; + buf[3u] = 0u; // clear EID flag in bit 32 } return eepromWrite(addr, buf, sizeof(buf)); @@ -195,22 +197,26 @@ eepromWriteCanId(U16 addr, const CanId *id) { // Bit 31 indicates standard/extended: 0=>std, 1=>ext. Status eepromReadCanId(U16 addr, CanId *id) { + U8 buf[sizeof(U32)]; Status status; // Read - status = eepromRead(addr, id->eid, sizeof(id->eid)); + status = eepromRead(addr, buf, sizeof(buf)); if (status != OK) { return FAIL; } // Unpack - if (id->eid[3u] & 0x80) { // bit 31 is standard/extended flag + if (buf[3u] & 0x80) { // bit 31 is standard/extended flag id->isExt = true; // extended - id->eid[3u] &= 0x1F; + id->eid = ((U32)buf[0u] << 0u) + | ((U32)buf[1u] << 8u) + | ((U32)buf[2u] << 16u) + | (((U32)buf[3u] & 0x1F) << 24u); } else { id->isExt = false; // standard - id->sid.lo = id->eid[0u]; - id->sid.hi = id->eid[1u] & 0x7; + id->sid = ((U16)buf[0u] << 0u) + | (((U16)buf[1u] & 0x07) << 8u); } return OK; @@ -31,7 +31,7 @@ typedef enum { // Used for writing/reading calibration tables. static const CanId tblCtrlFilter = { .isExt = true, - .eid = {0x00, 0x20, 0x27, 0x01}, // 12720XXh + .eid = 0x01272000, // 112720XXh }; // ID Control filter. @@ -39,14 +39,14 @@ static const CanId tblCtrlFilter = { // See `doc/datafmt.ps'. static const CanId idCtrlFilter = { .isExt = true, - .eid = {0x00, 0x21, 0x27, 0x01}, // 127210Xh + .eid = 0x01272100, // 127210Xh }; // Receive buffer 0 mask. // RXB0 receives Table and ID Control Frames. static const CanId rxb0Mask = { .isExt = true, - .eid = {0x00, 0xFF, 0xFF, 0x1F}, // all but LSB + .eid = 0x1FFFFF00, // all buf LSB }; // Receive buffer 1 mask. @@ -54,28 +54,28 @@ static const CanId rxb0Mask = { // The mask is permissive: all messages are accepted and filtered in software. static const CanId rxb1Mask = { .isExt = true, - .eid = {0u, 0u, 0u, 0u}, // accept all messages + .eid = 0u, // accept all messages }; // Calibration tables in EEPROM: // Each is 2*sizeof(U32)*TAB_ROWS = 256B -- too big for an 8-bit word. // That's why the offsets are hard-coded. -static const Table tachTbl = {{0x00, 0x00}}; // tachometer -static const Table speedTbl = {{0x01, 0x00}}; // speedometer -static const Table an1Tbl = {{0x02, 0x00}}; // analog channels... -static const Table an2Tbl = {{0x03, 0x00}}; -static const Table an3Tbl = {{0x04, 0x00}}; -static const Table an4Tbl = {{0x05, 0x00}}; +static const Table tachTbl = {0ul*TAB_SIZE}; // tachometer +static const Table speedTbl = {1ul*TAB_SIZE}; // speedometer +static const Table an1Tbl = {2ul*TAB_SIZE}; // analog channels... +static const Table an2Tbl = {3ul*TAB_SIZE}; +static const Table an3Tbl = {4ul*TAB_SIZE}; +static const Table an4Tbl = {5ul*TAB_SIZE}; // EEPROM address of CAN ID for each parameter. // Each of these addresses holds a U32 CAN ID. static const EepromAddr paramIdAddrs[NPARAM] = { - [TACH] = {0x06, 0x00}, // tachometer - [SPEED] = {0x06, 0x04}, // speedometer - [AN1] = {0x06, 0x08}, // analog channels... - [AN2] = {0x06, 0x0C}, - [AN3] = {0x06, 0x10}, - [AN4] = {0x06, 0x14}, + [TACH] = NPARAM*TAB_SIZE + 0ul*sizeof(U32), // tachometer + [SPEED] = NPARAM*TAB_SIZE + 1ul*sizeof(U32), // speedometer + [AN1] = NPARAM*TAB_SIZE + 2ul*sizeof(U32), // analog channels... + [AN2] = NPARAM*TAB_SIZE + 3ul*sizeof(U32), + [AN3] = NPARAM*TAB_SIZE + 4ul*sizeof(U32), + [AN4] = NPARAM*TAB_SIZE + 5ul*sizeof(U32), }; // CAN ID of each parameter @@ -173,20 +173,19 @@ respondIdCtrl(Param param) { // Pack param ID into response's DATA FIELD response.id = (CanId) { .isExt = true, - .eid = {param & 0xF, 0x21, 0x27, 0x01}, // 127210Xh + .eid = 0x01272100 | ((U32)param & 0x0F), // 127210Xh }; response.rtr = false; if (paramId.isExt) { // extended response.dlc = 4u; // U32 - // BE <- LE - response.data[0u] = paramId.eid[3u] & 0x1F; - response.data[1u] = paramId.eid[2u]; - response.data[2u] = paramId.eid[1u]; - response.data[3u] = paramId.eid[0u]; + response.data[0u] = (paramId.eid>>24u) & 0x1F; + response.data[1u] = (paramId.eid>>16u) & 0xFF; + response.data[2u] = (paramId.eid>>8u) & 0xFF; + response.data[3u] = (paramId.eid>>0u) & 0xFF; } else { // standard response.dlc = 2u; // U16 - response.data[0u] = paramId.sid.hi & 0x7; - response.data[1u] = paramId.sid.lo; + response.data[0u] = (paramId.sid>>8u) & 0x07; + response.data[1u] = (paramId.sid>>0u) & 0xFF; } // Transmit response @@ -202,22 +201,21 @@ setParamId(const CanFrame *frame) { // Extract param ID from DATA FIELD if (frame->dlc == 4u) { // extended - paramId.isExt = true; - // LE <- BE - paramId.eid[0u] = frame->data[3u]; - paramId.eid[1u] = frame->data[2u]; - paramId.eid[2u] = frame->data[1u]; - paramId.eid[3u] = frame->data[0u] & 0x1F; + paramId.isExt = true; + paramId.eid = ((U32)frame->data[3u] << 0u) + | ((U32)frame->data[2u] << 8u) + | ((U32)frame->data[1u] << 16u) + | (((U32)frame->data[0u] & 0x1F) << 24u); } else if (frame->dlc == 2u) { // standard paramId.isExt = false; - paramId.sid.lo = frame->data[1u]; - paramId.sid.hi = frame->data[0u] & 0x7; + paramId.sid = ((U16)frame->data[1u] << 0u) + | ((U16)frame->data[0u] << 8u); } else { return FAIL; // invalid DLC } // Set param's ID - param = frame->id.eid[0u] & 0xF; + param = frame->id.eid & 0xF; if ((U8)param < NPARAM) { // Update copy in EEPROM status = eepromWriteCanId(paramIdAddrs[param], ¶mId); @@ -243,7 +241,7 @@ handleIdCtrlFrame(const CanFrame *frame) { Param param; if (frame->rtr) { // REMOTE - param = frame->id.eid[0u] & 0xF; + param = frame->id.eid & 0xF; return respondIdCtrl(param); // respond with the parameter's CAN ID } else { // DATA return setParamId(frame); @@ -15,8 +15,10 @@ tabWrite(const Table *tab, U8 k, U16 key, U16 val) { return FAIL; } - U16 addr = addU16U8(tab->offset, k*TAB_ROW_SIZE); - U8 row[4u] = {key.lo, key.hi, val.lo, val.hi}; + U16 addr = tab->offset + k*TAB_ROW_SIZE; + U8 row[4u] = { + (key>>0u)&0xFF, (key>>8u)&0xFF, + (val>>0u)&0xFF, (val>>8u)&0xFF}; return eepromWrite(addr, row, sizeof(row)); } @@ -30,10 +32,10 @@ tabRead(const Table *tab, U8 k, U16 *key, U16 *val) { return FAIL; } - addr = addU16U8(tab->offset, k*TAB_ROW_SIZE); + addr = tab->offset + k*TAB_ROW_SIZE; status = eepromRead(addr, row, sizeof(row)); - *key = (U16){.lo=row[0u], .hi=row[1u]}; - *val = (U16){.lo=row[2u], .hi=row[3u]}; + *key = ((U16)row[0u]<<0u) | ((U16)row[1u]<<8u); + *val = ((U16)row[2u]<<0u) | ((U16)row[3u]<<8u); return status; } @@ -42,7 +44,6 @@ tabLookup(const Table *tab, U16 key, U16 *val) { U8 k; U16 tkey, tval1, tval2; Status status; - I8 ord; // Search for key for (k = 0u; (k < TAB_ROWS-1u); k++) { @@ -50,17 +51,15 @@ tabLookup(const Table *tab, U16 key, U16 *val) { if (status != OK) { return FAIL; } - ord = cmpU16(key, tkey); - if (ord == 0u) { // found exact key + if (key == tkey) { // found exact key *val = tval1; return OK; - } else if (ord > 0u) { // interpolate + } else if (key > tkey) { // interpolate status = tabRead(tab, k+1u, &tkey, &tval2); if (status != OK) { return FAIL; } - // Mean: (tval1+tval2)/2 - *val = rshiftU16(addU16(tval1, tval2), 1u); + *val = (tval1 + tval2) / 2u; return OK; } else { // less // continue @@ -21,10 +21,11 @@ */ enum { - TAB_KEY_SIZE = 4, // U32 - TAB_VAL_SIZE = 4, // U32 + TAB_KEY_SIZE = sizeof(U32), + TAB_VAL_SIZE = sizeof(U32), TAB_ROWS = 32, TAB_ROW_SIZE = TAB_KEY_SIZE + TAB_VAL_SIZE, + TAB_SIZE = TAB_ROWS * TAB_ROW_SIZE, }; typedef struct { diff --git a/fw/types.c b/fw/types.c deleted file mode 100644 index 1064379..0000000 --- a/fw/types.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <xc.h> - -#include <stdint.h> - -#include "types.h" - -U16 -addU16(U16 a, U16 b) { - a.hi += b.hi; - a.lo += b.lo; - if (STATUSbits.C) { - a.hi++; - } - return a; -} - -U16 -addU16U8(U16 a, U8 b) { - a.lo += b; - if (STATUSbits.C) { - a.hi++; - } - return a; -} - -U16 -lshiftU16(U16 a, U8 b) { - a.hi = (U8)(a.hi << b) | (a.lo >> (8u-b)); - a.lo <<= b; - return a; -} - -U16 -rshiftU16(U16 a, U8 b) { - a.lo = (U8)((a.hi >> (8u-b)) << (8u-b)) | (U8)(a.lo >> b); - a.hi >>= b; - return a; -} - -I8 -cmpU16(U16 a, U16 b) { - if (a.hi > b.hi) { - return 1; - } else if (a.hi < b.hi) { - return -1; - } else if (a.lo > b.lo) { - return 1; - } else if (a.lo < b.lo) { - return -1; - } else { - return 0; - } -} @@ -13,28 +13,27 @@ typedef enum { } Status; typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; + typedef int8_t I8; +typedef int16_t I16; +typedef int32_t I32; +// Number typedef struct { - U8 hi, lo; -} U16; - -// Little-endian 32-bit unsigned integer. -typedef U8 U32[4]; - -// a + b -U16 addU16(U16 a, U16 b); - -// a + b -U16 addU16U8(U16 a, U8 b); - -// a << b -U16 lshiftU16(U16 a, U8 b); - -// a >> b -U16 rshiftU16(U16 a, U8 b); - -// -1 if a < b -// 0 if a == b -// +1 if a > b -I8 cmpU16(U16 a, U16 b); + enum { + NUM_U8, + NUM_U16, + NUM_U32, + NUM_I8, + NUM_I16, + NUM_I32, + } type; + U8 u8; + U16 u16; + U32 u32; + I8 i8; + I16 i16; + I32 i32; +} Number; |