diff --git a/include/GD31xxOI.h b/include/GD31xxOI.h index b6c43bf..f991aaf 100644 --- a/include/GD31xxOI.h +++ b/include/GD31xxOI.h @@ -22,25 +22,22 @@ */ #include "stddef.h" -#include "stdbool.h" #include #include "delay.h" +#include "digio.h" -#define REQ_ADC_EXT 0x4001 -#define REQ_STAT1 0x2800 -#define REQ_STAT2 0x3000 -#define REQ_STAT3 0x3800 +class MGSPI { -/// SPI channels -enum SpiChannelMG -{ - MGSPI1_H = 1, - MGSPI2_H = 2, - MGSPI3_H = 3, - MGSPI1_L = 4, - MGSPI2_L = 5, - MGSPI3_L = 6, -}; +public: + static void Initialize(); + static void CyclicFunction(); + static uint16_t GetRawTemperature(int index) { return temps[index]; } + static uint16_t GetUdc() { return udc; } + +private: + static uint16_t temps[3]; + static uint16_t udc; -extern uint32_t Send16 (enum SpiChannelMG channel,uint16_t txData16); -extern uint32_t Config_MG (enum SpiChannelMG channel); + static uint32_t Send16(DigIo& cspin,uint16_t txData16); + static uint32_t ConfigureGateDriver(DigIo& cspin); +}; diff --git a/include/digio_prj.h b/include/digio_prj.h index cf766eb..2359986 100644 --- a/include/digio_prj.h +++ b/include/digio_prj.h @@ -3,8 +3,65 @@ #include "hwdefs.h" +//Since there are various HW variants we first declare all possible pins... + #define DIG_IO_LIST \ - DIG_IO_ENTRY(cruise_in, GPIOB, GPIO2, PinMode::INPUT_PD) \ + DIG_IO_ENTRY(cruise_in,,,) \ + DIG_IO_ENTRY(start_in,,,) \ + DIG_IO_ENTRY(brake_in,,,) \ + DIG_IO_ENTRY(mprot_in,,,) \ + DIG_IO_ENTRY(fwd_in,,,) \ + DIG_IO_ENTRY(rev_in,,,) \ + DIG_IO_ENTRY(emcystop_in,,,) \ + DIG_IO_ENTRY(bk_in,,,) \ + DIG_IO_ENTRY(bms_in,,,) \ + DIG_IO_ENTRY(ocur_in,,,) \ + DIG_IO_ENTRY(desat_in,,,) \ + DIG_IO_ENTRY(dcsw_out,,,) \ + DIG_IO_ENTRY(fan_out,,,) \ + DIG_IO_ENTRY(vtg_out,,,) \ + DIG_IO_ENTRY(prec_out,,,) \ + DIG_IO_ENTRY(led_out,,,) \ + DIG_IO_ENTRY(err_out,,,) \ + DIG_IO_ENTRY(temp0_out,,,) \ + DIG_IO_ENTRY(speed_out,,,) \ + DIG_IO_ENTRY(brk_out,,,) \ + DIG_IO_ENTRY(cs1_hi,,,) \ + DIG_IO_ENTRY(cs2_hi,,,) \ + DIG_IO_ENTRY(cs3_hi,,,) \ + DIG_IO_ENTRY(cs1_lo,,,) \ + DIG_IO_ENTRY(cs2_lo,,,) \ + DIG_IO_ENTRY(cs3_lo,,,) \ + DIG_IO_ENTRY(v5_ctrl,,,) \ + DIG_IO_ENTRY(intb_in,,,) \ + DIG_IO_ENTRY(inta_in,,,) \ + +//...Then we assign the physical GPIOs per variant + +#define DIG_IO_LIST_STD \ + DIG_IO_ENTRY(cruise_in, GPIOB, GPIO5, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(start_in, GPIOB, GPIO6, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(brake_in, GPIOA, GPIO2, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(mprot_in, GPIOA, GPIO3, PinMode::INPUT_PU) \ + DIG_IO_ENTRY(fwd_in, GPIOA, GPIO4, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(rev_in, GPIOC, GPIO6, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(emcystop_in, GPIOC, GPIO7, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(bk_in, GPIOB, GPIO12, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(bms_in, GPIOC, GPIO8, PinMode::INPUT_PD) \ + DIG_IO_ENTRY(ocur_in, GPIOA, GPIO1, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(desat_in, GPIOC, GPIO9, PinMode::INPUT_FLT) \ + DIG_IO_ENTRY(dcsw_out, GPIOC, GPIO13, PinMode::OUTPUT) \ + DIG_IO_ENTRY(fan_out, GPIOA, GPIO0, PinMode::OUTPUT) /* map to unused pin by default */ \ + DIG_IO_ENTRY(vtg_out, GPIOC, GPIO11, PinMode::OUTPUT) \ + DIG_IO_ENTRY(prec_out, GPIOB, GPIO1, PinMode::OUTPUT) \ + DIG_IO_ENTRY(led_out, GPIOC, GPIO12, PinMode::OUTPUT) \ + DIG_IO_ENTRY(err_out, GPIOC, GPIO10, PinMode::OUTPUT) \ + DIG_IO_ENTRY(temp0_out, GPIOC, GPIO10, PinMode::OUTPUT) \ + DIG_IO_ENTRY(speed_out, GPIOB, GPIO9, PinMode::OUTPUT) \ + DIG_IO_ENTRY(brk_out, GPIOC, GPIO5, PinMode::OUTPUT) \ + +#define DIG_IO_LIST_MG \ + DIG_IO_ENTRY(cruise_in, GPIOB, GPIO2, PinMode::INPUT_PD) \ DIG_IO_ENTRY(start_in, GPIOD, GPIO7, PinMode::INPUT_FLT) \ DIG_IO_ENTRY(brake_in, GPIOE, GPIO4, PinMode::INPUT_FLT) \ DIG_IO_ENTRY(mprot_in, GPIOE, GPIO5, PinMode::INPUT_PU) \ diff --git a/include/hwdefs.h b/include/hwdefs.h index 46011e3..d1f456d 100644 --- a/include/hwdefs.h +++ b/include/hwdefs.h @@ -45,7 +45,7 @@ typedef enum { - HW_REV1, HW_REV2, HW_REV3, HW_TESLA, HW_BLUEPILL, HW_PRIUS, HW_MINI, HW_LEAF2, HW_LEAF3, HW_BMWI3 + HW_REV1, HW_REV2, HW_REV3, HW_TESLA, HW_BLUEPILL, HW_PRIUS, HW_MINI, HW_LEAF2, HW_LEAF3, HW_BMWI3, HW_MG } HWREV; extern HWREV hwRev; diff --git a/include/param_prj.h b/include/param_prj.h index 183db62..a82276c 100644 --- a/include/param_prj.h +++ b/include/param_prj.h @@ -166,7 +166,6 @@ VALUE_ENTRY(opmode, OPMODES, 2000 ) \ VALUE_ENTRY(lasterr, errorListString, 2038 ) \ VALUE_ENTRY(status, STATUS, 2044 ) \ - VALUE_ENTRY(status_GD3100, STATUS3100, 2063 ) \ VALUE_ENTRY(udc, "V", 2001 ) \ VALUE_ENTRY(idc, "A", 2002 ) \ VALUE_ENTRY(il1, "A", 2003 ) \ @@ -202,12 +201,6 @@ VALUE_ENTRY(din_bms, ONOFF, 2032 ) \ VALUE_ENTRY(uptime, "10ms", 2054 ) \ VALUE_ENTRY(cpuload, "%", 2035 ) \ - VALUE_ENTRY(MG_Rx0, "dig", 2056 ) \ - VALUE_ENTRY(MG_Rx1, "dig", 2057 ) \ - VALUE_ENTRY(MG_Rx2, "dig", 2058 ) \ - VALUE_ENTRY(MG_Rx3, "dig", 2059 ) \ - VALUE_ENTRY(INT_L, ONOFF, 2064 ) \ - VALUE_ENTRY(INT_H, ONOFF, 2065 ) \ #define VALUES_SINE \ VALUE_ENTRY(ilmax, "A", 2005 ) \ diff --git a/src/GD31xxOI.cpp b/src/GD31xxOI.cpp index 2b1a661..019e4ba 100644 --- a/src/GD31xxOI.cpp +++ b/src/GD31xxOI.cpp @@ -22,9 +22,13 @@ */ #include "GD31xxOI.h" -#include "digio.h" +#include "hwinit.h" #include +#define REQ_ADC_EXT 0x4001 +#define REQ_STAT1 0x2800 +#define REQ_STAT2 0x3000 +#define REQ_STAT3 0x3800 // CRC table for polynomial 0x2F. static const uint8_t MGcrc_table[256] = { @@ -52,6 +56,51 @@ static const uint16_t MG_Gate_Config[24] = { 0X82B3, 0XA05A, 0XA470, 0X88DB, 0X8CD4, 0X9024, 0X964B, 0X9906, 0X9C3F, 0XAC00, 0XB400, 0X8440 }; +uint16_t MGSPI::temps[3]; +uint16_t MGSPI::udc; + +void MGSPI::Initialize() { + DigIo::v5_ctrl.Set(); //Turn on MG gate driver logic side 5v power after 2 seconds + DigIo::cs1_hi.Set(); //Disable all SPI CS lines on MG + DigIo::cs2_hi.Set(); + DigIo::cs3_hi.Set(); + DigIo::cs1_lo.Set(); + DigIo::cs2_lo.Set(); + DigIo::cs3_lo.Set(); + + tim5_setup();//Enable gate drive psu on MG board + spi_setup();//MG gate drivers + uDelay(20); + + ConfigureGateDriver(DigIo::cs1_hi); //configure all 6 MG gate drivers + ConfigureGateDriver(DigIo::cs1_hi); //must be sent twice to 1H as its a bit dumb + ConfigureGateDriver(DigIo::cs2_hi); + ConfigureGateDriver(DigIo::cs3_hi); + ConfigureGateDriver(DigIo::cs1_lo); + ConfigureGateDriver(DigIo::cs2_lo); + ConfigureGateDriver(DigIo::cs2_lo); +} + +void MGSPI::CyclicFunction() { + static uint8_t MG_Cycler = 0; + + switch (MG_Cycler){ + case 0: + temps[0] = Send16(DigIo::cs1_hi, REQ_ADC_EXT);//HS Temp 1 + break; + case 1: + temps[1] = Send16(DigIo::cs2_hi, REQ_ADC_EXT);//HS Temp 1 + break; + case 2: + temps[2] = Send16(DigIo::cs3_hi, REQ_ADC_EXT);//HS Temp 1 + break; + case 3: + udc = Send16(DigIo::cs3_lo, REQ_ADC_EXT);//HS Temp 1 + break; + } + + MG_Cycler = (MG_Cycler + 1) & 0x7; //count from 0-7 +} ////////////////////////////////////////////////////////////////////////////////////////// // Function name: Calculate_MGSPI_CRC @@ -93,63 +142,23 @@ static uint8_t Calculate_SPI_CRC(uint16_t inData) { // /// @return uint32_t - Returns 16 bit answer from device ////////////////////////////////////////////////////////////////////////////////////////// -uint32_t Send16 (enum SpiChannelMG channel,uint16_t txData16) { +uint32_t MGSPI::Send16 (DigIo& cspin, uint16_t txData16) { uint8_t i=0; uint8_t rxData8[3]; uint16_t outData=0; uint8_t txData8[3]; // Set chip select low - switch(channel) { - case 1: - DigIo::cs1_hi.Clear(); - break; - case 2: - DigIo::cs2_hi.Clear(); - break; - case 3: - DigIo::cs3_hi.Clear(); - break; - case 4: - DigIo::cs1_lo.Clear(); - break; - case 5: - DigIo::cs2_lo.Clear(); - break; - case 6: - DigIo::cs3_lo.Clear(); - break; - default: - break; - } + cspin.Clear(); + txData8[0]=txData16>>8; txData8[1]=txData16 & 0xFF; txData8[2]=Calculate_SPI_CRC(txData16); + for(i=0; i<3; i++) { rxData8[i]=spi_xfer(SPI1,txData8[i]); } - switch(channel) { - case 1: - DigIo::cs1_hi.Set(); - break; - case 2: - DigIo::cs2_hi.Set(); - break; - case 3: - DigIo::cs3_hi.Set(); - break; - case 4: - DigIo::cs1_lo.Set(); - break; - case 5: - DigIo::cs2_lo.Set(); - break; - case 6: - DigIo::cs3_lo.Set(); - break; - default: - break; - } + cspin.Set(); outData=(rxData8[1] | rxData8[0]<<8) & 0x3FF; return outData; } @@ -163,11 +172,11 @@ uint32_t Send16 (enum SpiChannelMG channel,uint16_t txData16) { // /// @return uint32_t - Returns 16 bit answer from device ////////////////////////////////////////////////////////////////////////////////////////// -uint32_t Config_MG (enum SpiChannelMG channel) { +uint32_t MGSPI::ConfigureGateDriver(DigIo& cspin) { uint32_t dummyData; for(int i=0; i<=23; i++) { uDelay(20);// need to allow 20us per command as per datasheet - dummyData=Send16(channel,MG_Gate_Config[i]); + dummyData=Send16(cspin, MG_Gate_Config[i]); } return dummyData; diff --git a/src/hwinit.cpp b/src/hwinit.cpp index aeaef70..dde404b 100644 --- a/src/hwinit.cpp +++ b/src/hwinit.cpp @@ -141,13 +141,13 @@ static HWREV ReadVariantResistor() //See here for variants: https://openinverter.org/wiki/Mini_Mainboard#Hardware_detection if ((result1 + result2) < 30) return HW_BMWI3; //connected to MISO so always low else if (result2 > 3700) return HW_MINI; //might have to compare this against result1 later + else if (result1 > 327 && result1 < 347) return HW_MG; else if (result1 > 510 && result1 < 630) return HW_LEAF3; else return HW_MINI; } HWREV detect_hw() { - return HW_REV3;//bodge for test //Check if PB3 and PC10 are connected (mini mainboard) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO10); gpio_set(GPIOC, GPIO10); @@ -190,7 +190,7 @@ HWREV io_setup() hwRev = detect_hw(); ANA_IN_CONFIGURE(ANA_IN_LIST); - DIG_IO_CONFIGURE(DIG_IO_LIST); + DIG_IO_CONFIGURE(DIG_IO_LIST_STD); switch (hwRev) { @@ -205,6 +205,9 @@ HWREV io_setup() //Essentially disable error output by mapping it to an unused pin DigIo::err_out.Configure(GPIOB, GPIO9, PinMode::INPUT_FLT); break; + case HW_MG: + DIG_IO_CONFIGURE(DIG_IO_LIST_MG); + break; case HW_BLUEPILL: ANA_IN_CONFIGURE(ANA_IN_LIST_BLUEPILL); DIG_IO_CONFIGURE(DIG_IO_BLUEPILL); @@ -402,6 +405,6 @@ void tim5_setup()//Used on VCT6 for MG gate drive power supply timer_set_period(TIM5, 270);//frequency 133khz timer_set_oc_value(TIM5, TIM_OC1,125);//125=46% high timer_set_oc_value(TIM5, TIM_OC2,150);//140=44% high - //timer_enable_counter(TIM5); + timer_enable_counter(TIM5); } diff --git a/src/stm32_sine.cpp b/src/stm32_sine.cpp index 2cc10e3..5826b4e 100644 --- a/src/stm32_sine.cpp +++ b/src/stm32_sine.cpp @@ -60,15 +60,6 @@ static CanSdo* canSdo; static Terminal* terminal; static bool seenBrakePedal = false; -static uint8_t MG_psu_timer=20;//2 sec delay to fire up MG logic side 5v gate supply -static bool MG_psu_on=false; -static bool MG_ReadStat=false; -static uint8_t MG_com_cnt=10; -static uint32_t MG_gate_stat=0; -uint16_t MGrxData[6]; -static uint8_t MG_Cycler=5; - - static void Ms100Task(void) { DigIo::led_out.Toggle(); @@ -98,6 +89,8 @@ static void Ms100Task(void) VehicleControl::SelectDirection(); VehicleControl::CruiseControl(); + if (HW_MG == hwRev) MGSPI::CyclicFunction(); + #if CONTROL == CTRL_SINE //uac = udc * amp/maxamp / sqrt(2) float uac = Param::GetFloat(Param::udc) * SineCore::GetAmp(); @@ -109,54 +102,6 @@ static void Ms100Task(void) if (Param::GetInt(Param::canperiod) == CAN_PERIOD_100MS) canMap->SendAll(); - //////////////////////MG/////////////////////////////////////////////////////////////// - if(MG_psu_timer!=0 && !MG_psu_on) MG_psu_timer--; - if(MG_psu_timer==0 && !MG_psu_on) - { - timer_enable_counter(TIM5);//Turn on MG gate driver HV side PSU - DigIo::v5_ctrl.Set();//Turn on MG gate driver logic side 5v power after 2 seconds - MG_psu_on=true; - } - MG_com_cnt--; - - if(MG_com_cnt==0) - { - - MG_com_cnt=10; - if(MG_Cycler==0) - { - MG_ReadStat=!MG_ReadStat; - MG_Cycler=5; - } - - if(!MG_ReadStat) - { - - } - - - MG_Cycler--; - - MGrxData[0]=Send16(MGSPI1_H,REQ_ADC_EXT);//HS Temp 1 - MGrxData[1]=Send16(MGSPI2_H,REQ_ADC_EXT);//HS Temp 2 - MGrxData[2]=Send16(MGSPI3_H,REQ_ADC_EXT);//HS Temp 3 - MGrxData[3]=Send16(MGSPI3_L,REQ_ADC_EXT);//UDC - - - - - } - - Param::SetInt(Param::status_GD3100, 0); - Param::SetInt(Param::MG_Rx0,MGrxData[0]); - Param::SetInt(Param::MG_Rx1,MGrxData[1]); - Param::SetInt(Param::MG_Rx2,MGrxData[2]); - Param::SetInt(Param::MG_Rx3,MGrxData[3]); - - Param::SetInt(Param::INT_H,DigIo::inta_in.Get());//Display status of gate driver interrupt line - Param::SetInt(Param::INT_L,DigIo::intb_in.Get()); - - /////////////////////////////////////////////////////////////////////////////////////// } static void RunCharger(float udc) @@ -464,15 +409,7 @@ extern "C" int main(void) nvic_setup(); parm_load(); ErrorMessage::SetTime(1); - //////////MG////////////////////////////// - DigIo::v5_ctrl.Set();//Turn on MG gate driver logic side 5v power after 2 seconds - DigIo::cs1_hi.Set();//Disable all SPI CS lines on MG - DigIo::cs2_hi.Set(); - DigIo::cs3_hi.Set(); - DigIo::cs1_lo.Set(); - DigIo::cs2_lo.Set(); - DigIo::cs3_lo.Set(); - ///////////////////////////////////////// + if (HW_MG == hwRev) MGSPI::Initialize(); Param::SetInt(Param::pwmio, pwmio_setup(Param::GetBool(Param::pwmpol))); MotorVoltage::SetMaxAmp(SineCore::MAXAMP); @@ -505,19 +442,6 @@ extern "C" int main(void) Param::Change(Param::nodeid); Param::Change(Param::outmode); write_bootloader_pininit(Param::GetBool(Param::bootprec), Param::GetBool(Param::pwmpol)); - /////////////MG///////////////////////// - tim5_setup();//Enable gate drive psu on MG board - spi_setup();//MG gate drivers - timer_enable_counter(TIM5);//Turn on MG gate driver HV side PSU - uDelay(20); - MG_gate_stat=Config_MG(MGSPI1_H);//configure all 6 MG gate drivers - MG_gate_stat=Config_MG(MGSPI1_H);//must be sent twice to 1H as its a bit dumb - MG_gate_stat=Config_MG(MGSPI2_H); - MG_gate_stat=Config_MG(MGSPI3_H); - MG_gate_stat=Config_MG(MGSPI1_L); - MG_gate_stat=Config_MG(MGSPI2_L); - MG_gate_stat=Config_MG(MGSPI3_L); - while(1) { diff --git a/src/vehiclecontrol.cpp b/src/vehiclecontrol.cpp index 40b1267..3c61210 100644 --- a/src/vehiclecontrol.cpp +++ b/src/vehiclecontrol.cpp @@ -32,6 +32,7 @@ #include "my_math.h" #include "pwmgeneration.h" #include "hwinit.h" +#include "GD31xxOI.h" #define PRECHARGE_TIMEOUT 500 //5s #define CAN_TIMEOUT 50 //500ms @@ -478,11 +479,10 @@ float VehicleControl::ProcessUdc() BmwAdcAcquire(); udcRaw = bmwAdcValues[ADC_CHAN_UDC]; } + else if (HW_MG == hwRev) + udcRaw = MGSPI::GetUdc(); else - { - //udcRaw = AnaIn::udc.Get(); - udcRaw = Param::GetInt(Param::MG_Rx3);//MG bodge - } + udcRaw = AnaIn::udc.Get(); udcFiltered = IIRFILTER(udcFiltered, udcRaw, 2); udcfp = (udcFiltered - udcofs) / udcgain; @@ -617,8 +617,7 @@ void VehicleControl::GetTemps(float& tmphs, float &tmpm) TempMeas::Sensors snshs = (TempMeas::Sensors)Param::GetInt(Param::snshs); TempMeas::Sensors snsm = (TempMeas::Sensors)Param::GetInt(Param::snsm); - //int tmphsi = AnaIn::tmphs.Get(); - int tmphsi = MIN(MIN(Param::GetInt(Param::MG_Rx0),Param::GetInt(Param::MG_Rx1)),Param::GetInt(Param::MG_Rx3));//MG bodge + int tmphsi = AnaIn::tmphs.Get(); int tmpmi = AnaIn::tmpm.Get(); tmpm = TempMeas::Lookup(tmpmi, snsm); @@ -640,6 +639,12 @@ void VehicleControl::GetTemps(float& tmphs, float &tmpm) tmphs = 166.66f - tmphsi / priusTempCoeff; } + else if (hwRev == HW_MG) + { + tmphsi = MIN(MGSPI::GetRawTemperature(0), MGSPI::GetRawTemperature(1)); + tmphsi = MIN(MGSPI::GetRawTemperature(2), tmphsi); + tmphs = tmphsi / 32; + } else if (snshs == TempMeas::TEMP_BMWI3HS) { //For the next line to work, BmwAdcGet() must be called regularly @@ -649,8 +654,7 @@ void VehicleControl::GetTemps(float& tmphs, float &tmpm) } else { - //tmphs = TempMeas::Lookup(tmphsi, snshs); - tmphs = 0;//tmphsi;//MG Bodge + tmphs = TempMeas::Lookup(tmphsi, snshs); } } }