diff --git a/GDI-4ch/firmware/can.cpp b/GDI-4ch/firmware/can.cpp index b6e5e9f..137e606 100644 --- a/GDI-4ch/firmware/can.cpp +++ b/GDI-4ch/firmware/can.cpp @@ -1,6 +1,8 @@ #include "can.h" #include "hal.h" +#include "efifeatures.h" + #include #include #include "sent_canbus_protocol.h" @@ -21,7 +23,7 @@ static char VERSION[] = {compilationYear() / 100, compilationYear() % 100, compilationMonth(), compilationDay()}; extern GDIConfiguration configuration; -extern Pt2001 chip; +extern Pt2001 chips[EFI_PT2001_CHIPS]; extern bool isOverallHappyStatus; static const CANConfig canConfig500 = @@ -44,17 +46,17 @@ static void countTxResult(msg_t msg) { } } -int canGetOutputCanIdBase(void) +int canGetOutputCanIdBase(size_t chip) { - return (configuration.outputCanID + boardGetId() * GDI4_BASE_ADDRESS_OFFSET); + return (configuration.outputCanID + (boardGetId() + chip) * GDI4_BASE_ADDRESS_OFFSET); } -int canGetInputCanIdBase() +int canGetInputCanIdBase(size_t chip) { - return (configuration.inputCanID + boardGetId() * GDI4_BASE_ADDRESS_OFFSET); + return (configuration.inputCanID + (boardGetId() + chip) * GDI4_BASE_ADDRESS_OFFSET); } -void SendSomething(int baseID) { +void SendSomething(size_t chip, int baseID) { CANTxFrame m_frame; m_frame.IDE = CAN_IDE_EXT; @@ -67,7 +69,7 @@ void SendSomething(int baseID) { m_frame.data8[0] = configuration.inputCanID; m_frame.data8[1] = configuration.updateCounter; m_frame.data8[2] = isOverallHappyStatus; - m_frame.data8[6] = (int)chip.fault; + m_frame.data8[6] = (int)chips[chip].fault; m_frame.data8[7] = GDI4_MAGIC; msg_t msg = canTransmitTimeout(&CAND1, CAN_ANY_MAILBOX, &m_frame, CAN_TX_TIMEOUT_100_MS); @@ -163,6 +165,8 @@ static int intTxCounter = 0; static THD_WORKING_AREA(waCanTxThread, 256); void CanTxThread(void*) { + chRegSetThreadName("CAN TX"); + while (1) { intTxCounter++; chThdSleepMilliseconds(1000 / CAN_TX_PERIOD_MS); @@ -171,19 +175,23 @@ void CanTxThread(void*) continue; // we were told to be silent } - // keep constant while sending whole banch of messages - int outID = canGetOutputCanIdBase(); + for (size_t i = 0; i < EFI_PT2001_CHIPS; i++) { + // keep constant while sending whole banch of messages + int outID = canGetOutputCanIdBase(i); - if (intTxCounter % (1000 / CAN_TX_PERIOD_MS) == 0) { - sendOutConfiguration(outID); - } - if (intTxCounter % (1000 / CAN_TX_PERIOD_MS) == 0) { - sendOutVersion(outID); - } + if (intTxCounter % (1000 / CAN_TX_PERIOD_MS) == 0) { + sendOutConfiguration(outID); + } + if (intTxCounter % (1000 / CAN_TX_PERIOD_MS) == 0) { + sendOutVersion(outID); + } - SendSomething(outID); + SendSomething(i, outID); - sendOutSentData(outID); + if (i == 0) { + sendOutSentData(outID); + } + } } } @@ -205,6 +213,8 @@ static float getFloat(CANRxFrame *frame, int offset) { static THD_WORKING_AREA(waCanRxThread, 256); void CanRxThread(void*) { + chRegSetThreadName("CAN RX"); + while (1) { CANRxFrame frame; msg_t msg = canReceiveTimeout(&CAND1, CAN_ANY_MAILBOX, &frame, TIME_INFINITE); @@ -213,13 +223,6 @@ void CanRxThread(void*) if (msg != MSG_OK) { continue; } - size_t writeCount = 0; - -// writeCount = chsnprintf(printBuffer, sizeof(printBuffer), "eid=%d data[0]=%d dlc=%d\n\n\n\n\n\n\n", -// frame.EID, -// frame.data8[0], -// frame.DLC); - // Ignore std frames, only listen to ext if (frame.IDE != CAN_IDE_EXT) { @@ -231,35 +234,44 @@ void CanRxThread(void*) continue; } - bool withNewValue = false; - int inputID = canGetInputCanIdBase(); - // TODO: valudate DLC and IDE - if (frame.EID == inputID) { - ASSIGN_IF_CHANGED(configuration.BoostVoltage, getInt(&frame, 1)); - ASSIGN_IF_CHANGED(configuration.BoostCurrent, getFloat(&frame, 3)); - ASSIGN_IF_CHANGED(configuration.TBoostMin, getInt(&frame, 5)); - } else if (frame.EID == inputID + 1) { - ASSIGN_IF_CHANGED(configuration.TBoostMax, getInt(&frame, 1)); - ASSIGN_IF_CHANGED(configuration.PeakCurrent, getFloat(&frame, 3)); - ASSIGN_IF_CHANGED(configuration.TpeakDuration, getInt(&frame, 5)); - } else if (frame.EID == inputID + 2) { - ASSIGN_IF_CHANGED(configuration.TpeakOff, getInt(&frame, 1)); - ASSIGN_IF_CHANGED(configuration.Tbypass, getInt(&frame, 3)); - ASSIGN_IF_CHANGED(configuration.HoldCurrent, getFloat(&frame, 5)); - } else if (frame.EID == inputID + 3) { - ASSIGN_IF_CHANGED(configuration.TholdOff, getInt(&frame, 1)); - ASSIGN_IF_CHANGED(configuration.THoldDuration, getInt(&frame, 3)); - ASSIGN_IF_CHANGED(configuration.PumpPeakCurrent, getFloat(&frame, 5)); - } else if (frame.EID == inputID + 4) { - ASSIGN_IF_CHANGED(configuration.PumpHoldCurrent, getFloat(&frame, 1)); - ASSIGN_IF_CHANGED(configuration.outputCanID, getInt(&frame, 3)); - } - if (withNewValue) { - saveConfiguration(); - chip.restart(); + for (size_t i = 0; i < EFI_PT2001_CHIPS; i++) { +// size_t writeCount = 0; + +// writeCount = chsnprintf(printBuffer, sizeof(printBuffer), "eid=%d data[0]=%d dlc=%d\n\n\n\n\n\n\n", +// frame.EID, +// frame.data8[0], +// frame.DLC); + + bool withNewValue = false; + int inputID = canGetInputCanIdBase(i); + // TODO: valudate DLC and IDE + if (frame.EID == inputID) { + ASSIGN_IF_CHANGED(configuration.BoostVoltage, getInt(&frame, 1)); + ASSIGN_IF_CHANGED(configuration.BoostCurrent, getFloat(&frame, 3)); + ASSIGN_IF_CHANGED(configuration.TBoostMin, getInt(&frame, 5)); + } else if (frame.EID == inputID + 1) { + ASSIGN_IF_CHANGED(configuration.TBoostMax, getInt(&frame, 1)); + ASSIGN_IF_CHANGED(configuration.PeakCurrent, getFloat(&frame, 3)); + ASSIGN_IF_CHANGED(configuration.TpeakDuration, getInt(&frame, 5)); + } else if (frame.EID == inputID + 2) { + ASSIGN_IF_CHANGED(configuration.TpeakOff, getInt(&frame, 1)); + ASSIGN_IF_CHANGED(configuration.Tbypass, getInt(&frame, 3)); + ASSIGN_IF_CHANGED(configuration.HoldCurrent, getFloat(&frame, 5)); + } else if (frame.EID == inputID + 3) { + ASSIGN_IF_CHANGED(configuration.TholdOff, getInt(&frame, 1)); + ASSIGN_IF_CHANGED(configuration.THoldDuration, getInt(&frame, 3)); + ASSIGN_IF_CHANGED(configuration.PumpPeakCurrent, getFloat(&frame, 5)); + } else if (frame.EID == inputID + 4) { + ASSIGN_IF_CHANGED(configuration.PumpHoldCurrent, getFloat(&frame, 1)); + ASSIGN_IF_CHANGED(configuration.outputCanID, getInt(&frame, 3)); + } + if (withNewValue) { + saveConfiguration(); + chips[i].restart(); + } + // if (writeCount > 0) + // uartStartSend(&UARTD1, writeCount, printBuffer); } -// if (writeCount > 0) -// uartStartSend(&UARTD1, writeCount, printBuffer); chThdSleepMilliseconds(100); } diff --git a/GDI-4ch/firmware/can.h b/GDI-4ch/firmware/can.h index aa8d556..4781421 100644 --- a/GDI-4ch/firmware/can.h +++ b/GDI-4ch/firmware/can.h @@ -1,5 +1,9 @@ #pragma once #include +#include + +int canGetOutputCanIdBase(size_t chip); +int canGetInputCanIdBase(size_t chip); void InitCan(); diff --git a/GDI-4ch/firmware/efifeatures.h b/GDI-4ch/firmware/efifeatures.h new file mode 100644 index 0000000..59ac8f6 --- /dev/null +++ b/GDI-4ch/firmware/efifeatures.h @@ -0,0 +1,11 @@ +/** + * @file efifeatures.h + * + * @brief In this header we can configure which firmware modules are used. + */ + +#pragma once + +#ifndef EFI_PT2001_CHIPS + #define EFI_PT2001_CHIPS 1 +#endif diff --git a/GDI-4ch/firmware/main.cpp b/GDI-4ch/firmware/main.cpp index 06f5235..abf423c 100644 --- a/GDI-4ch/firmware/main.cpp +++ b/GDI-4ch/firmware/main.cpp @@ -1,3 +1,5 @@ +#include "efifeatures.h" + #include "pt2001impl.h" #include "can.h" @@ -24,16 +26,31 @@ static void InitPins() { bool isOverallHappyStatus = false; -static const SPIConfig spiCfg = { - .circular = false, - .end_cb = nullptr, - .ssport = GPIOB, - .sspad = 2, - .cr1 = - SPI_CR1_DFF | - SPI_CR1_MSTR | - SPI_CR1_CPHA | SPI_CR1_BR_1 | SPI_CR1_SPE, +static const SPIConfig spiCfg[EFI_PT2001_CHIPS] = { + { + .circular = false, + .end_cb = nullptr, + .ssport = GPIOB, + .sspad = 2, + .cr1 = + SPI_CR1_DFF | + SPI_CR1_MSTR | + SPI_CR1_CPHA | SPI_CR1_BR_1 | SPI_CR1_SPE, + .cr2 = SPI_CR2_SSOE + }, +#if (EFI_PT2001_CHIPS > 1) + { + .circular = false, + .end_cb = nullptr, + .ssport = GPIOB, + .sspad = 3, + .cr1 = + SPI_CR1_DFF | + SPI_CR1_MSTR | + SPI_CR1_CPHA | SPI_CR1_BR_1 | SPI_CR1_SPE, .cr2 = SPI_CR2_SSOE + }, +#endif }; void GDIConfiguration::resetToDefaults() { @@ -68,8 +85,7 @@ GDIConfiguration *getConfiguration() { return &configuration; } - -bool Pt2001::init() { +void initPt2001Interface() { palSetPadMode(GPIOA, 5, PAL_MODE_STM32_ALTERNATE_PUSHPULL); // sck palSetPadMode(GPIOA, 6, PAL_MODE_INPUT); // miso palSetPadMode(GPIOA, 7, PAL_MODE_STM32_ALTERNATE_PUSHPULL); // mosi @@ -79,6 +95,11 @@ bool Pt2001::init() { palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); // chip select palSetPad(GPIOB, 2); +#if (EFI_PT2001_CHIPS > 1) + palSetPadMode(GPIOB, 3, PAL_MODE_OUTPUT_PUSHPULL); // chip select for second chip + palSetPad(GPIOB, 3); +#endif + // Set debug pins remap mode to use PB4 as normal pin AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; palSetPadMode(GPIOB, 4, PAL_MODE_OUTPUT_PUSHPULL); // DRVEN @@ -89,17 +110,24 @@ bool Pt2001::init() { palSetPadMode(GPIOB, 7, PAL_MODE_INPUT_PULLDOWN); // flag0 - driver = &SPID1; - spiStart(driver, &spiCfg); - spiUnselect(driver); +#if (EFI_PT2001_CHIPS > 1) + // release reset (if shared between chips) + chThdSleepMilliseconds(1); + palSetPad(GPIOB, 5); +#endif +} - // Wait 1/2 second for things to wake up - chThdSleepMilliseconds(500); +bool Pt2001::init(SPIDriver *spi, const SPIConfig *cfg) { + driver = spi; + spiCfg = cfg; + + spiStart(driver, spiCfg); + spiUnselect(driver); return restart(); } -Pt2001 chip; +Pt2001 chips[EFI_PT2001_CHIPS]; mfs_error_t flashState; @@ -127,10 +155,19 @@ int main() { palSetPadMode(LED_GREEN_PORT, LED_GREEN_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(LED_GREEN_PORT, LED_GREEN_PIN); - bool isOverallHappyStatus = false; + bool isOverallHappyStatus = true; + initPt2001Interface(); + // Wait 1/2 second for things to wake up + chThdSleepMilliseconds(500); +#if (EFI_PT2001_CHIPS > 1) + // DRVEN = 1 (if shared between chips) + palSetPad(GPIOB, 4); +#endif // reminder that +12v is required for PT2001 to start - isOverallHappyStatus = chip.init(); + for (size_t i = 0; i < EFI_PT2001_CHIPS; i++) { + isOverallHappyStatus &= chips[i].init(&SPID1, &spiCfg[i]); + } while (true) { if (isOverallHappyStatus) { diff --git a/GDI-4ch/firmware/pt2001impl.h b/GDI-4ch/firmware/pt2001impl.h index 0027404..e627dbc 100644 --- a/GDI-4ch/firmware/pt2001impl.h +++ b/GDI-4ch/firmware/pt2001impl.h @@ -1,6 +1,7 @@ #include "ch.h" #include "hal.h" #include "persistence.h" +#include "efifeatures.h" #include @@ -10,6 +11,7 @@ class Pt2001 : public Pt2001Base { public: // returns true if init successful bool init(); + bool init(SPIDriver *spi, const SPIConfig *cfg); protected: void acquireBus() override { @@ -19,14 +21,23 @@ class Pt2001 : public Pt2001Base { } void select() override { + /* Acquire ownership of the bus. */ + spiAcquireBus(driver); + /* Setup transfer parameters. */ + spiStart(driver, spiCfg); + /* Slave Select assertion. */ spiSelect(driver); } void deselect() override { + /* Slave Select de-assertion. */ spiUnselect(driver); + /* Ownership release. */ + spiReleaseBus(driver); } bool errorOnUnexpectedFlag() override { + return false; } uint16_t sendRecv(uint16_t tx) override { @@ -40,19 +51,29 @@ class Pt2001 : public Pt2001Base { // GPIO reset and enable pins void setResetB(bool state) override { +#if (EFI_PT2001_CHIPS == 1) if (state) { palSetPad(GPIOB, 5); } else { palClearPad(GPIOB, 5); } +#else + //do not drive shared gpio + (void)state; +#endif } void setDriveEN(bool state) override { +#if (EFI_PT2001_CHIPS == 1) if (state) { palSetPad(GPIOB, 4); } else { palClearPad(GPIOB, 4); } +#else + //do not drive shared gpio + (void)state; +#endif } // GPIO inputs for various pins we need @@ -141,4 +162,5 @@ class Pt2001 : public Pt2001Base { private: SPIDriver* driver; + const SPIConfig* spiCfg; }; diff --git a/GDI-4ch/firmware/sent.cpp b/GDI-4ch/firmware/sent.cpp index 33be688..329dd85 100644 --- a/GDI-4ch/firmware/sent.cpp +++ b/GDI-4ch/firmware/sent.cpp @@ -205,7 +205,7 @@ void sent_channel::Info() { chprintf(chp, "Interval errors %lu short, %lu long\r\n", statistic.ShortIntervalErr, statistic.LongIntervalErr); chprintf(chp, "Total frames %lu with CRC error %lu (%d%%)\r\n", statistic.FrameCnt, statistic.CrcErrCnt, 100 * statistic.CrcErrCnt / statistic.FrameCnt); chprintf(chp, "Total slow channel messages %lu + %lu with crc6 errors %lu (%d%%)\r\n", statistic.sc12, statistic.sc16, statistic.scCrcErr, 100 * statistic.scCrcErr / (statistic.sc12 + statistic.sc16)); - chprintf(chp, "Sync errors %lu alive=%d\n", statistic.SyncErr, aliveCounter++); + chprintf(chp, "Sync errors %lu alive=%d\r\n", statistic.SyncErr, aliveCounter++); #endif GmPressureDebug(); } @@ -249,6 +249,8 @@ void SENT_ISR_Handler(uint8_t channel, uint16_t clocks, uint8_t flags) { /* Decoder thread. */ /*==========================================================================*/ static void SentDecoderThread(void*) { + chRegSetThreadName("SEND RX"); + while (true) { msg_t ret; msg_t msg; diff --git a/GDI-4ch/firmware/uart.cpp b/GDI-4ch/firmware/uart.cpp index 62ff08b..994ec35 100644 --- a/GDI-4ch/firmware/uart.cpp +++ b/GDI-4ch/firmware/uart.cpp @@ -2,12 +2,15 @@ #include "hal.h" #include "chprintf.h" +#include "efifeatures.h" + #include "uart.h" #include "io_pins.h" #include "persistence.h" #include "fault.h" #include "pt2001impl.h" #include "sent.h" +#include "can.h" /** * @brief Global variables @@ -26,7 +29,7 @@ extern bool isOverallHappyStatus; extern mfs_error_t flashState; extern int canWriteOk; extern int canWriteNotOk; -extern Pt2001 chip; +extern Pt2001 chips[EFI_PT2001_CHIPS]; extern GDIConfiguration configuration; static int counter = 0; @@ -34,27 +37,34 @@ static int counter = 0; static THD_WORKING_AREA(waUartThread, 256); static void UartThread(void*) { + chRegSetThreadName("UART debug"); while (true) { counter = (counter + 1) % 1000; - if (chip.fault != McFault::None) { - chprintf(chp, "FAULT fault=%d status=%x status2=%x 0x1A6=%x 0x1A7=%x 0x1A8=%x\r\n", - (int)chip.fault, - chip.status, - chip.status5, - chip.status6, - chip.status7, - chip.status8); - } else { - chprintf(chp, "%x %d %d HAPPY fault=%d status=%x status2=%x flash=%d %d CAN o/e %d %d\r\n", - configuration.inputCanID, - (int)(configuration.PumpPeakCurrent * 1000), - configuration.updateCounter, - (int)chip.fault, - chip.status, - chip.status5, - (int)flashState, counter, - canWriteOk, canWriteNotOk); + + chprintf(chp, "Flash=%d %d CAN o/e %d %d\r\n", + (int)flashState, counter, + canWriteOk, canWriteNotOk); + for (size_t i = 0; i < EFI_PT2001_CHIPS; i++) { + if (chips[i].fault != McFault::None) { + chprintf(chp, "%d: FAULT fault=%d status=%x status2=%x 0x1A6=%x 0x1A7=%x 0x1A8=%x\r\n", + i, + (int)chips[i].fault, + chips[i].status, + chips[i].status5, + chips[i].status6, + chips[i].status7, + chips[i].status8); + } else { + chprintf(chp, "%d: 0x%03x %d %d HAPPY fault=%d status=%x status2=%x\r\n", + i, + canGetInputCanIdBase(i), + (int)(configuration.PumpPeakCurrent * 1000), + configuration.updateCounter, + (int)chips[i].fault, + chips[i].status, + chips[i].status5); + } } sentDebug();