System Management code
Dependencies: CANBuffer mbed SystemManagement mbed-rtos
System Management code for Penn Electric Racing
Functions:
Controls Fans and Pumps via instruction from CAN Messages, ramps them up over time to prevent damage
Turns on/off DC-DC converter via instruction from CAN Messages
SysMngmt.cpp
- Committer:
- martydd3
- Date:
- 2014-10-10
- Revision:
- 7:5f6e31faa08e
- Parent:
- 6:6a04210a3f4f
File content as of revision 7:5f6e31faa08e:
/* Reads CAN Messages and various data inputs, outputs using Xbee radio modules Revised Sept 30, 2014: Began analyzing and commenting program, trying to figure out what the hell it does (Martin Deng) */ #include "SysMngmt.h" #include "Get_IMD.h" #include "PollSwitch.h" #include "TemperatureRead.h" #include "Store_RTC.h" #include "XBee_Lib.h" #include "CANBuffer.h" #include "mbed.h" #include "rtos.h" #include "Watchdog.cpp" #include "FanPump.h" #include "DC_DC.h" #include "PollSwitch.h" //Possible problems in IMD coz change of counter //Possible problems in BatteryStatus coz change in library /* Attach Ticker every 10msec to Get IMD Poll Switches Temperature Read Get Battery State End Ticker Send message through CAN CAN interrupt Rx Interrupt Recieve CAN message into a buffer. Return Buffer values(as long as !empty) -> SD Card, Xbee -> remove element extern "C" void CAN_IRQHandler(void) { CANMessage Rxmsg; CAN_SysM.read(Rxmsg); RecieveBuffer.add(Rxmsg); } http://developer.mbed.org/users/AjK/notebook/getting-closer-to-the-hardware/ extern "C" means this is linked assuming it's C code C++ linker appearently adds extra crap with the function arguments keeping functions of this kind from linking properly Interrupt handler, This is probably linked to the Timer 2 interrupt request somewhere by the libraries extern "C" void TIMER2_IRQHandler(void) { if((LPC_TIM2->IR & 0x01) == 0x01) // if MR0 interrupt { // This probably shouldn't be here, never have a printf() in an interrupt, locks up the main thread // printf("Every 1ms\n\r"); LPC_TIM2->IR |= 1 << 0; // Clear MR0 interrupt flag // gonna hope all these calculations are correct // writes to RTC store, but there's no read code here // 2 misleading things. First, RTC store writes to a general purpose register // secondly, no code reads from this register in this .cpp, but maybe some other code does Bat_I_Ratio=BatISense.read(); BATA_msec=(((Bat_I_Ratio*3.3) - BAT_ISENSE_OFFSET_V)/BAT_ISENSE_INCREMENT); BATmA_Hr+=(BATA_msec*MSEC_HRS); store.write(BATmA_Hr,0); DC_I_Ratio=DCSense.read(); DCA_msec=(((DC_I_Ratio*3.3) - DC_DC_ISENSE_OFFSET_V)/DC_DC_ISENSE_INCREMENT); store.write(DCA_msec,1); LPC_TIM2->TCR |= (1<<1); //Reset Timer1 LPC_TIM2->TCR &= ~(1<<1); //Re Enable Timer1 } } Appears to read a whole bunch of DigitalOut pins in void PollSwitch(), store the value in uint16_t Rxpoll, and write the result to the CAN bus void Poll() { uint16_t Rxpoll; uint16_t recv,temp,i=0; //Test char Result[4]={0}; Rxpoll=PollSwitch(); Result[0]=(char)(Rxpoll&0x00ff); Result[1]=(char)((Rxpoll&0xff00)>>8); CANMessage Txmsg(410,Result,sizeof(Result)); CAN_SysM.write(Txmsg); //Test recv=(((uint16_t)Txmsg.data[1]<<8) | (0x00ff&(uint16_t)Txmsg.data[0])); printf("Recv:%d\n\r",recv); while(i <= 12) { temp=recv; if(((temp & (1 << i))>>i)==1) pc.printf("Switch OFF:%d\n\r",i); ++i; } } void Temp() { float DC_DC_Temperature, Coolant1_Temperature, Coolant2_Temperature, ChargerFET_Temperature; float Resistance; float Vadc; int i; ftc send, recv; recv.FLOAT=0.0; send.FLOAT=0.0; Vadc=DC_DC.read()*VDD; Resistance=((float)R10K*Vadc)/((float)VDD + Vadc); DC_DC_Temperature=ReadTemp(TR_NXFT15XH103FA_Map, Resistance, TABLE_SIZE_NXFT15XH103FA); send.FLOAT=DC_DC_Temperature; CANMessage Txmsg_DC_DC(450,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_DC_DC); for(i=0; i<4;i++) recv.C_FLOAT[i]=Txmsg_DC_DC.data[i]; pc.printf("DC_DC:%f\n\r",recv.FLOAT); Vadc=ChargerFET.read()*VDD; Resistance=((float)R10K*Vadc)/((float)VDD + Vadc); ChargerFET_Temperature=ReadTemp(TR_NXFT15XH103FA_Map, Resistance, TABLE_SIZE_NXFT15XH103FA); send.FLOAT=ChargerFET_Temperature; CANMessage Txmsg_ChargerFET(451,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_ChargerFET); for(i=0; i<4;i++) recv.C_FLOAT[i]=Txmsg_ChargerFET.data[i]; pc.printf("ChargerFET:%f\n\r",recv.FLOAT); Vadc=Coolant1.read()*VDD; Resistance=((float)R10K*Vadc)/((float)VDD + Vadc); Coolant1_Temperature=ReadTemp(TR_NTCLP00E3103H_Map, Resistance, TABLE_SIZE_NTCLP00E3103H); send.FLOAT=Coolant1_Temperature; CANMessage Txmsg_Coolant1(452,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_Coolant1); //Control Fans for(i=0; i<4;i++) recv.C_FLOAT[i]=Txmsg_Coolant1.data[i]; pc.printf("Coolant1:%f\n\r",recv.FLOAT); Vadc=Coolant2.read()*VDD; Resistance=((float)R10K*Vadc)/((float)VDD + Vadc); Coolant2_Temperature=ReadTemp(TR_NTCLP00E3103H_Map, Resistance, TABLE_SIZE_NTCLP00E3103H); send.FLOAT=Coolant2_Temperature; CANMessage Txmsg_Coolant2(453,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_Coolant2); //Control Fans for(i=0; i<4;i++) recv.C_FLOAT[i]=Txmsg_Coolant2.data[i]; pc.printf("Coolant2:%f\n\r",recv.FLOAT); } void IMD() { IMD_Measurement_Output IMD_Signal; char status[4]; ftc send; IMD_Signal=Get_Measurement(); send.FLOAT=IMD_Signal.Frequency; CANMessage Txmsg_Frequency(421,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_Frequency); send.FLOAT=IMD_Signal.Duty_Cycle; CANMessage Txmsg_DutyCycle(422,send.C_FLOAT,sizeof(send.C_FLOAT)); CAN_SysM.write(Txmsg_DutyCycle); status[0]=Result.Encoded_Status; CANMessage Txmsg_Status(423,status,sizeof(status)); CAN_SysM.write(Txmsg_Status); } */ /* Activates a whole crapload of functions and pins on the chip void Init() { Timers to call various functions at different intervals These things behave weirdly when wait(ms) is involved. Probably have to rewrite //ReadIMD.attach(&IMD,0.1); //PollSDSwitch.attach(&Poll,0.1); //ReadTemperature.attach(&Temp,0.1); //ReadBatteryState.attach(&Battery,0.1); Initialize Timer2 for Battery State LPC_SC 0x400F C000 (System Control) ->PCONP 0x400F C0C4 (Power Control for Peripherals Register) |= (1<<22) 22 Bit (Timer 2 power/clock control bit) ->PCLKSEL1 Peripheral Clock Selection register 1 (controls rate of clock signal supplied to peripheral) |= ((1<<12) | (1<<13)); 12:13 Bits (Peripheral Clock Selection for TIMER2) LPC_TIM2 0x4009 0000 (Timer 2) ->TCR 0x4009 0004 (Timer Control Register) |= (1<<0); 0 Bit (Counter Enable) ->MR0 0x4009 0018 (Match Register) ->MCR 0x4009 0014 (Match Control Register) What to do when Match Register matches the Timer Counter |= (1<<0); 0 Bit (Interrupt on MR0, interrupt generated when MR0 matches the value in TC) LPC_SC->PCONP |= (1<<22); //PoewerOn Timer/Counter2 LPC_SC->PCLKSEL1 |= ((1<<12) | (1<<13)); //Prescale Timer2 CCLK/8 LPC_TIM2->TCR |= (1<<0); //Enable Timer2 LPC_TIM2->MR0 = 11999; // 1msec LPC_TIM2->MCR |= (1<<0); Nested Vectored Interrupt Controller (NVIC) NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) sets priority of an interrupt IRQn_Type Interrupt number definitions Interrupt Request (IRQ) NVIC_EnableIRQ(IRQn_Type IRQn) Enable external interrupt (in this case, the TIMER2_IRQHandler(void) function above gets called every time Timer2 generates an interrupt signal) NVIC_SetPriority(TIMER0_IRQn,200); //IMD Capture Interrupt NVIC_SetPriority(TIMER1_IRQn,200); //IMD 1msec sampling Interrupt NVIC_SetPriority(TIMER2_IRQn,1); //Battery 1msec sampling Interrupt NVIC_SetPriority(TIMER3_IRQn,255); //mbed Timer/Ticker/Wait Interrupt NVIC_SetPriority(CAN_IRQn,2); NVIC_EnableIRQ(TIMER2_IRQn); //Enable TIMER2 IRQ CAN_SysM.mode(CAN::GlobalTest); //NVIC_EnableIRQ(CAN_IRQn); //NVIC_EnableIRQ(CANActivity_IRQn); } Main Loop: Currently reads CANMessages from Can interface (Pins: rd = p30, td = p29) Send CANMessage data through XBee radio transmitters */ CANBuffer rxBuffer(CAN1, MEDIUM); XBee250x XbeeTx; Serial pc1(USBTX,USBRX); char sys_src_id = 4; // source address of system management int main() { CANMessage rx_msg; Watchdog wdt; wdt.kick(10.0); pc1.baud(115200); FanPump fanPump(&rxBuffer); DC dc_dc(&fanPump, &rxBuffer); PollSwitch pollSwitch(&rxBuffer); fanPump.start_update(); dc_dc.start_update(); pollSwitch.start_update(); while(1) { if(rxBuffer.rxRead(rx_msg)){ char src_addr = (rx_msg.id & 0x0700) >> 8; // get bits 10:8 if(src_addr == sys_src_id){ char cont_id = (rx_msg.id & 0x00FF); // get bits 7:0 // only control fans of dc_dc converter is on if(cont_id == RX_FAN_ID && dc_dc.is_on()) { fanPump.set_fan((FanSelect)rx_msg.data[0], rx_msg.data[1]); } if(cont_id == RX_DC_DC_ID){ dc_dc.set(rx_msg.data[0]); } } // check for correct src_addr } // check CANBuffer wdt.kick(); } // main while loop }