Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
SysMngmt.cpp
- Committer:
- martydd3
- Date:
- 2014-10-08
- Revision:
- 5:9258b685fea6
- Parent:
- 4:e31528929150
- Child:
- 6:6a04210a3f4f
File content as of revision 5:9258b685fea6:
/*
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"
//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;
char sys_src_id = 4; // source address of system management
char fan_id = 1; // first byte of CANData, last byte states the duty cycle, second-last states which fan to control
Thread *fan_threads[4] = {NULL, NULL, NULL, NULL}; // Threads currently running on the 4 output pins
/*
Pins for Fans and Pumps
PUMP_PWM = p2.0
FAN1_PWM = p2.1
FAN2_PWM = p2.2
FAN3_PWM = p2.3
*/
PwmOut pump_pwm(P2_0);
PwmOut fan1_pwm(P2_1);
PwmOut fan2_pwm(P2_2);
PwmOut fan3_pwm(P2_3);
char fan1_duty = 0;
char fan2_duty = 0;
char fan3_duty = 0;
char pump_duty = 0;
int tx_fan_id = ((int)sys_src_id << 8)&((int)fan_id);
// duty goes from 0 to 100
void rampFans(void const *arg){
char *data = (char *)arg;
// bounds checking
char duty = data[1];
if(duty > 100)
return;
char pin_id = data[0];
if(pin_id > 3)
return;
char *cur_duty;
PwmOut *out_pin;
switch(pin_id){
case 0: cur_duty = &pump_duty;
out_pin = &pump_pwm;
break;
case 1: cur_duty = &fan1_duty;
out_pin = &fan1_pwm;
break;
case 2: cur_duty = &fan2_duty;
out_pin = &fan2_pwm;
break;
case 3: cur_duty = &fan3_duty;
out_pin = &fan3_pwm;
break;
default:
return;
}
while(*cur_duty != duty){
if(duty > *cur_duty){
*cur_duty += 10;
if(*cur_duty > duty)
*cur_duty = duty;
} else if(duty < *cur_duty){
*cur_duty -= 10;
if(*cur_duty < duty)
*cur_duty = duty;
}
out_pin->write((*cur_duty)*0.01);
Thread::wait(10);
}
}
void updateFans(void const *arg){
char data[4] = {0, 0, 0, 0};
while(1){
data[0] = pump_duty;
data[1] = fan1_duty;
data[2] = fan2_duty;
data[3] = fan3_duty;
CANMessage txMessage(tx_fan_id, data, 4);
rxBuffer.txWrite(txMessage);
Thread::wait(100);
}
}
char dc_id = 0; // first byte of CANData, last byte states whether to toggle on (1) or off (0)
DigitalOut dcPin(p20);
bool dc_on = false;
int tx_dc_id = ((int)sys_src_id << 8)&((int)dc_id);
void toggleDC_DC(bool toggle){
//dcPin turns on DC_DC converter when 0, off when 1
if(toggle && !dc_on){
dcPin = 0;
dc_on = true;
} else if(!toggle && dc_on){
dcPin = 1;
dc_on = false;
}
}
void updateDC(void const *arg){
char data[4] = {0, 0, 0, 0};
while(1){
data[0] = dc_on;
CANMessage txMessage(tx_dc_id, data, 4);
rxBuffer.txWrite(txMessage);
Thread::wait(100);
}
}
int main() {
CANMessage rx_msg;
//turn off DC-DC converter on startup
toggleDC_DC(false);
//CANMessage update threads
Thread fan_update(updateFans);
Thread dc_update(updateDC);
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 == fan_id && dc_on)
{
char duty = rx_msg.data[1];
if(duty > 100)
break;
char pin_id = rx_msg.data[0];
if(pin_id > 3)
break;
if(fan_threads[pin_id] != NULL){
fan_threads[pin_id]->terminate();
free(fan_threads[pin_id]);
}
fan_threads[pin_id] = new Thread(rampFans, rx_msg.data);
}
if(cont_id == dc_id){
toggleDC_DC(rx_msg.data[0]);
}
} // check for correct src_addr
} // check CANBuffer
} // main while loop
}
