void checkCBS(unsigned int *voltageArray, unsigned char *currentModule, unsigned char numModules)
{
//*
	unsigned char action = BALANCEOFF;
	unsigned char dataReceived[8];	//maximum length that can be recieved
	unsigned char lengthReceived, flagsReceived;
	unsigned long addressReceived = 0;
	unsigned int my_CAN_id = ((unsigned int) *currentModule) << 2;
	unsigned int lowestVoltage = 50000;
	unsigned char lowestModule = *currentModule;
	unsigned char i;
	//determine the lowest module
	for(i=0; i<numModules;++i)
	{
		if(voltageArray[i]<lowestVoltage)
		{
			lowestVoltage = voltageArray[i];
			lowestModule = i;
		}
	}
	//turn off CBS power to the previously low module if it's actually charging
	//check to see if we have received a comfirm message from the slave
	if(*currentModule != MODULE_ID_NULL)
	{
		while(addressReceived != (MASK_CBS | my_CAN_id))
		{
			//keep sending the message until something responds
			while(!ECANSendMessage(MASK_BPS_MASTER | MASK_CBS | my_CAN_id, &action, 1, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
			//read message
			while(!ECANReceiveMessage(&addressReceived, &dataReceived, &lengthReceived, &flagsReceived));
		}
	}
	//turn on CBS power to the new low module if low module is low enough
	if(lowestVoltage < (CUTOFF_VOLTAGE_HIGH - 3000))
	{
		my_CAN_id = ((unsigned int)lowestModule) << 2;
		addressReceived = 0;
		action = BALANCEON;
		//check to see if we have received a comfirm message from the slave
		while(addressReceived != (MASK_CBS | my_CAN_id))
		{
			//keep sending the message until something responds
			while(!ECANSendMessage(MASK_BPS_MASTER | MASK_CBS | my_CAN_id, &action, 1, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
			//read message
			while(!ECANReceiveMessage(&addressReceived, &dataReceived, &lengthReceived, &flagsReceived));
		}
		*currentModule = lowestModule;
	}
	else
	{
		*currentModule = MODULE_ID_NULL;
	}
	//print out the result
	printf("CBS=%d\n\r",*currentModule);
	while(!ECANSendMessage((MASK_BPS_MASTER|MASK_BPS_READING|MASK_CBS), currentModule, 1, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));	
	//*/
	return;
}
예제 #2
0
void main()
{
	unsigned long id;
	BYTE cpt_RB4;
	BYTE cpt_RB5;
    BYTE data_envoi;
    BYTE data_recu[8];
    BYTE dataLen;
    int i;
    
    ECAN_RX_MSG_FLAGS flags;
	init();
	
	cpt_RB4 = 0;
	cpt_RB5 = 0;
	data_envoi = 0;
	
	for (i = 0; i < 8;i++)
		data_recu[i] = 0xFF;
	
	printf(NL NL "début programme" NL);
    ECANInitialize();
    ECANSetBaudRate(2, 4, 8, 8, 8);
    
	while(1)
	{
		if(TRUE == ECANReceiveMessage(&id, data_recu, &dataLen, &flags))
		{
			PIC1_ONLY printf("ECAN: reçu %u octet(s) : %u" NL, dataLen, data_recu[0]);
			led_afficher_int(data_recu[0]);
		}
		
		
		if(bouton_RB4_pressed())
		{
			cpt_RB4 = cpt_RB4 + 1;
			
			data_envoi = (BYTE)cpt_RB4;
			while (!ECANSendMessage(0, &data_envoi, 1, 0));
			PIC1_ONLY printf("compteur de RB4 : %u" NL, cpt_RB4);
			
			led_afficher_int(cpt_RB4);
		}
			
		if(bouton_RB5_pressed())
		{
			cpt_RB5 = cpt_RB5 + 1;
			
			data_envoi = (BYTE)cpt_RB5;
			while (!ECANSendMessage(0, &data_envoi, 1, 0));
			PIC1_ONLY printf("compteur de RB5 : %u" NL, cpt_RB5);
			
			led_afficher_int(cpt_RB5);
		}
	}
}
void sendData(long current,unsigned char currentModule, long energy)
{
	printf("BC=%ld\n\r",current);
	while(!ECANSendMessage((MASK_BPS_MASTER|MASK_BPS_READING), &current, 4, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
	while(!ECANSendMessage((MASK_BPS_MASTER|MASK_BPS_READING|MASK_CBS), &currentModule, 1, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
	while(!ECANSendMessage((MASK_BPS_MASTER|MASK_BPS_READING|MASK_ENERGY), &energy, 4, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
	printf("CBS=%d\n\r",currentModule);	
	//printf("E=%ld\n\r",energy);
	return;
}
예제 #4
0
/**
 * void send_fast_can(void)
 *
 * Samples and sends fast speed sensor channels on CAN if the interval has passed
 */
void send_fast_can(void) {
  if (millis - fast_send_tmr >= FAST_MSG_SEND) {

#if FRONT // Sample and send FRONT fast speed sensor channels

    double spfl_samp = (double) sample(ADC_SPFL_CHN);
    uint16_t spfl = (uint16_t) ((10.0 * (5.0 - ((spfl_samp / 4095.0) * 5.0))) /
        SUS_POT_SCL);

    double spfr_samp = (double) sample(ADC_SPFR_CHN);
    uint16_t spfr = (uint16_t) ((10.0 * (5.0 - ((spfr_samp / 4095.0) * 5.0))) /
        SUS_POT_SCL);

    double bpf_samp = (double) sample(ADC_BPF_CHN);
    uint16_t bpf = (uint16_t) (((62.5 * ((bpf_samp / 4095.0) * 5.0)) -
        31.25) / BRK_PRS_SCL);

    double bpr_samp = (double) sample(ADC_BPR_CHN);
    uint16_t bpr = (uint16_t) (((62.5 * ((bpr_samp / 4095.0) * 5.0)) -
        31.25) / BRK_PRS_SCL);

    ((uint16_t*) data)[SPFL_BYTE / 2] = spfl;
    ((uint16_t*) data)[SPFR_BYTE / 2] = spfr;
    ((uint16_t*) data)[BPF_BYTE / 2] = bpf;
    ((uint16_t*) data)[BPR_BYTE / 2] = bpr;
    ECANSendMessage(ANALOG_FRONT_ID + 0x1, data, 8, ECAN_TX_FLAGS);

#elif REAR // Sample and send REAR fast speed sensor channels

    double sprl_samp = (double) sample(ADC_SPRL_CHN);
    uint16_t sprl = (uint16_t) ((10.0 * (5.0 - ((sprl_samp / 4095.0) * 5.0))) /
        SUS_POT_SCL);

    double sprr_samp = (double) sample(ADC_SPRR_CHN);
    uint16_t sprr = (uint16_t) ((10.0 * (5.0 - ((sprr_samp / 4095.0) * 5.0))) /
        SUS_POT_SCL);

    uint16_t eos = 0; //TODO

    double bcd_samp = (double) sample(ADC_BCD_CHN);
    uint16_t bcd = (uint16_t) (((187.5 * ((bcd_samp / 4095.0) * 5.0)) -
        468.75) / CUR_DRAW_SCL);

    ((uint16_t*) data)[SPRL_BYTE / 2] = sprl;
    ((uint16_t*) data)[SPRR_BYTE / 2] = sprr;
    ((uint16_t*) data)[EOS_BYTE / 2] = eos;
    ((uint16_t*) data)[BCD_BYTE / 2] = bcd;
    ECANSendMessage(ANALOG_REAR_ID + 0x1, data, 8, ECAN_TX_FLAGS);

#endif

    fast_send_tmr = millis;
  }
}
예제 #5
0
/**
 * void send_diag_can(void)
 *
 * Sends the diagnostic CAN message if the interval has passed.
 */
void send_diag_can(void) {
  if (millis - diag_send_tmr >= DIAG_MSG_SEND) {
    ((uint16_t*) data)[UPTIME_BYTE / 2] = seconds;

#if FRONT
    ECANSendMessage(ANALOG_FRONT_ID + 0x0, data, 2, ECAN_TX_FLAGS);
#elif REAR
    ECANSendMessage(ANALOG_REAR_ID + 0x0, data, 2, ECAN_TX_FLAGS);
#endif

    diag_send_tmr = millis;
  }
}
예제 #6
0
파일: can.c 프로젝트: Yalir/Archi1A
void can_send(Command c, BYTE param)
{
	BYTE data_envoi[2];
	data_envoi[0] = c;
	data_envoi[1] = param;
	while (!ECANSendMessage(0, data_envoi, 2, 0));
}
예제 #7
0
/**
 * void send_slow_can(void)
 *
 * Samples and sends slow speed sensor channels on CAN if the interval has passed
 */
void send_slow_can(void) {
  if (millis - slow_send_tmr >= SLOW_MSG_SEND) {

#if REAR // Sample and send REAR slow speed sensor channels

    double ctri_samp = (double) sample(ADC_CTRI_CHN);
    double ctri_volt = ((ctri_samp / 4095.0) * 5.0);
    int16_t ctri = (int16_t) (convert_ntc_res(ctri_volt, M12H_COEFF) / TEMP_SCL);

    double ctro_samp = (double) sample(ADC_CTRO_CHN);
    double ctro_volt = ((ctro_samp / 4095.0) * 5.0);
    int16_t ctro = (int16_t) (convert_ntc_res(ctro_volt, M12H_COEFF) / TEMP_SCL);

    double ctsp_samp = (double) sample(ADC_CTSP_CHN);
    double ctsp_volt = ((ctsp_samp / 4095.0) * 5.0);
    int16_t ctsp = (int16_t) (convert_ntc_res(ctsp_volt, PSTF_COEFF) / TEMP_SCL);

    ((int16_t*) data)[CTRI_BYTE / 2] = ctri;
    ((int16_t*) data)[CTRO_BYTE / 2] = ctro;
    ((int16_t*) data)[CTSP_BYTE / 2] = ctsp;
    ECANSendMessage(ANALOG_REAR_ID + 0x2, data, 6, ECAN_TX_FLAGS);

#endif

    slow_send_tmr = millis;
  }
}
예제 #8
0
/**
 * void send_med_can(void)
 *
 * Samples and sends medium speed sensor channels on CAN if the interval has passed
 */
void send_med_can(void) {
  if (millis - med_send_tmr >= MED_MSG_SEND) {

#if FRONT // Sample and send FRONT medium speed sensor channels

    double strp_samp = (double) sample(ADC_STRP_CHN);
    uint16_t strp = (uint16_t) (((90.0 * ((strp_samp / 4095.0) * 5.0)) -
        45.0) / STRP_SCL);

    double apps0_samp = (double) sample(ADC_APPS0_CHN);
    uint16_t apps0 = (uint16_t) (((25.0 * ((apps0_samp / 4095.0) * 5.0)) -
        12.5) / APPS_SCL);

    double apps1_samp = (double) sample(ADC_APPS1_CHN);
    uint16_t apps1 = (uint16_t) (((25.0 * ((apps1_samp / 4095.0) * 5.0)) -
        12.5) / APPS_SCL);

    double ptdp_samp = (double) sample(ADC_PTDP_CHN);
    uint16_t ptdp = (uint16_t) (((3.06458 * ((ptdp_samp / 4095.0) * 5.0)) -
        1.53229) / PTDP_SCL);

    ((uint16_t*) data)[STRP_BYTE / 2] = strp;
    ((uint16_t*) data)[APPS0_BYTE / 2] = apps0;
    ((uint16_t*) data)[APPS1_BYTE / 2] = apps1;
    ((uint16_t*) data)[PTDP_BYTE / 2] = ptdp;
    ECANSendMessage(ANALOG_FRONT_ID + 0x2, data, 8, ECAN_TX_FLAGS);

#elif REAR // Sample and send REAR medium speed sensor channels

    double cpsp_samp = (double) sample(ADC_CPSP_CHN);
    uint16_t cpsp = (uint16_t) (((1.37552 * ((cpsp_samp / 4095.0) * 5.0)) -
        0.18707) / CPSP_SCL);

    uint16_t mcd_samp = sample(ADC_MCD_CHN);
    uint16_t mcd = (uint16_t) (((187.5 * ((mcd_samp / 4095.0) * 5.0)) -
        468.75) / CUR_DRAW_SCL);

    ((uint16_t*) data)[CPSP_BYTE / 2] = cpsp;
    ((uint16_t*) data)[MCD_BYTE / 2] = mcd;
    ECANSendMessage(ANALOG_REAR_ID + 0x3, data, 4, ECAN_TX_FLAGS);

#endif

    med_send_tmr = millis;
  }
}
예제 #9
0
파일: clignos.c 프로젝트: ckiw/projetITI
void InterruptServiceHigh() {


    if (PIR3bits.RXB0IF || PIR3bits.RXB1IF) { //si message dans un buffer CAN lit le message
        //        unsigned long id;
        //        BYTE data[8];
        //        BYTE dataLen;
        //        ECAN_RX_MSG_FLAGS msgFlag;
        //
        //        while (!ECANReceiveMessage(&id, data, &dataLen, &msgFlag)); //remet le flag à 0
        //        switch (id) {
        //            case 0x123:
        //
        //                break;
        //
        //        }
    }

    if (PIR1bits.RCIF) {
        //Reinitialise le flag d'interruption de l'USART
        PIR1bits.RCIF = 0;
    }

    if (INTCONbits.INT0IF) { //si interruption sur INT0/RB0
        BYTE data[2];
        data[0] = LATDbits.LATD0;
        data[1] = LATDbits.LATD1;
        //voir page 117 si erreur


        ECANSendMessage(0x222, data, 2, 0b00000011);
        INTCONbits.INT0IF = 0; // Reset flag interruption

    }
    //        if (INTCON3bits.INT1IF) { //si interruption sur RB1

    //        INTCON3bits.INT1IF = 0; // Reset flag interruption

    //    }

    if (INTCONbits.RBIF) { //si interruption sur RB4 à RB7
        INTCONbits.RBIF = 0; // Reset flag interruption
    }



    if (INTCONbits.TMR0IF) {
        //Reinitialise le flag d'interruption du timer0
        INTCONbits.TMR0IF = 0;
        //Prescale le timer0
        //TMR0H = 0xF3;
        //TMR0L = 0xC9;

    }
}
예제 #10
0
파일: clignos.c 프로젝트: ckiw/projetITI
void main() {

    BYTE data = 0;

    TRISBbits.TRISB0 = 1; // rb0 en entrée (bouton)
    TRISBbits.TRISB1 = 1; // rb1 en entrée (bouton)

    //Configure les interruptions externes sur INT0 sur front (1:montant 0:descendant)
    INTCON2bits.INTEDG0 = 0;
    //Active les interruptions externes sur INT0
    INTCONbits.INT0IE = 1;

    //Configure les interruptions externes sur INT1 sur front (1:montant 0:descendant)
    INTCON2bits.INTEDG1 = 0;
    //Configure l'interruption externe INT1 sur 1:Haut prio 0:Basse prio
    INTCON3bits.INT1IP = 1;
    //Active les interruptions externes sur INT1
    INTCON3bits.INT1IE = 1;

    //Active l'interruption sur les changement de RB4 à RB7 p117
    INTCONbits.RBIE = 1;
    //Initialise le flag interruption sur les changement de RB4 à RB7
    INTCONbits.RBIF = 0;
    //Haute priorité sur interruption sur les changement de RB4 à RB7
    INTCON2bits.RBIP = 1;

    //Configure l'oscillateur interne sur 4MHz
    OSCCON = 0xEE;
    //Active les priorités sur interruption
    RCONbits.IPEN = 1;
    //Active les interruptions de haute prio
    INTCONbits.GIE = 1;
    //Active les interruptions de basse prio
    INTCONbits.PEIE = 1;

    TRISDbits.TRISD0 = 1; // rb0 en entrée (bouton)
    TRISDbits.TRISD1 = 1; // rb1 en entrée (bouton)


    ECANInitialize();



    ECANSendMessage(0x224, &data, 8, 0b00000011);

    while (1) {





    }
}
예제 #11
0
void main(void)
{
    unsigned long id;
    BYTE data[4];
    BYTE dataLen;
    ECAN_RX_MSG_FLAGS flags;


    ECANInitialize();

    // This function is for illustration purpose only.
    // It shows how an application would perform run-time initialization.
    // Normally, ECANInitialize() would initialize  ECAN module
    // as per ECAN.def options.  You would do run-time initialization
    // only if the ECAN optoins need to be changed at run-time.
    //RunTimeInitialization();

    while( !ECANSendMessage(0x123, data, 0, ECAN_TX_STD_FRAME) );


    do
    {
        while( !ECANReceiveMessage(&id, data, &dataLen, &flags) )
        {
            // Pushed down RB4 will fill-up FIFO/buffers.
            while( PORTB_RB4 == 0 );
        }


        id++;
        while( !ECANSendMessage(id, data, dataLen, flags) );

        // Delay so that when we are transmitting contents of FIFO all at once,
        // CANKing can receive it correctly without overflowing its buffer.
        id = 0xafff;
        while( id-- );
    } while(1);
}
예제 #12
0
void main(void) {

	/*************************
	 * Variable Declarations *
	 *************************/

    BYTE radio_sw[2], drs_over_sw[2], fan_over_sw[2], fuel_map_sw[2], paddle_l_sw[2], paddle_r_sw[2];
    BYTE ADLmsg[8];
	BYTE cycleStates[2], intensity;
	unsigned int bounceTimer[2];
	unsigned int CAN_tmr;


    /*********************
     * Oscillator Set-Up *
     *********************/
    #ifdef INTERNAL
            // OSCTUNE
            OSCTUNEbits.INTSRC = 0;		// Internal Oscillator Low-Frequency Source Select (1 for 31.25 kHz from 16MHz/512 or 0 for internal 31kHz)
            OSCTUNEbits.PLLEN = 1;		// Frequency Multiplier PLL Select (1 to enable)
            OSCTUNEbits.TUN5 = 0;		// Fast RC Oscillator Frequency Tuning (seems to be 2's comp encoding)
            OSCTUNEbits.TUN4 = 0;		// 011111 = max
            OSCTUNEbits.TUN3 = 0;		// ... 000001
            OSCTUNEbits.TUN2 = 0;		// 000000 = center (running at calibrated frequency)
            OSCTUNEbits.TUN1 = 0;		// 111111 ...
            OSCTUNEbits.TUN0 = 0;		// 100000

            // OSCCCON
            OSCCONbits.IDLEN = 1;		// Idle Enable Bit (1 to enter idle mode after SLEEP instruction else sleep mode is entered)
            OSCCONbits.IRCF2 = 1;		// Internal Oscillator Frequency Select Bits
            OSCCONbits.IRCF1 = 1;		// When using HF, settings are:
            OSCCONbits.IRCF0 = 1;		// 111 - 16 MHz, 110 - 8MHz (default), 101 - 4MHz, 100 - 2 MHz, 011 - 1 MHz
            OSCCONbits.SCS1 = 0;
            OSCCONbits.SCS0 = 0;

            // OSCCON2
            OSCCON2bits.MFIOSEL = 0;

            while(!OSCCONbits.HFIOFS);	// wait for stable clock

    #else
            // OSCTUNE
            OSCTUNEbits.INTSRC = 0;		// Internal Oscillator Low-Frequency Source Select (1 for 31.25 kHz from 16MHz/512 or 0 for internal 31kHz)
            OSCTUNEbits.PLLEN = 1;		// Frequency Multiplier PLL Select (1 to enable)

            // OSCCCON
            OSCCONbits.SCS1 = 0;		// select configuration chosen oscillator
            OSCCONbits.SCS0 = 0;		// SCS = 00

            // OSCCON2
            OSCCON2bits.MFIOSEL = 0;

            while(!OSCCONbits.OSTS);	// wait for stable external clock
    #endif

    /*********************
     * Peripherals Setup *
     *********************/

	// turn on and configure the A/D converter module
	OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_4_TAD, ADC_CH0 & ADC_INT_OFF, ADC_REF_VDD_VDD & ADC_REF_VDD_VSS & ADC_NEG_CH0);
	ANCON0 = 0b00100111;	// AN0 - 2 and AN5 are analog
	ANCON1 = 0x00;          // rest are digital
	TRISAbits.TRISA0 = INPUT;
	TRISAbits.TRISA1 = INPUT;
	TRISAbits.TRISA2 = INPUT;
	TRISAbits.TRISA5 = INPUT;

	// turn on and configure the TIMER1 oscillator
	OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_128);
	WriteTimer0(0x82);		// load timer register
	millis = 0;				// clear milliseconds count
	INTCONbits.TMR0IE = 1;	// turn on timer0 interupts

    // SPI setup
    SSPSTATbits.CKE = 1;		// SPI Clock Select, 1 = transmit on active to idle
    SSPCON1bits.CKP = 0;		// Clock Polarity Select, 0 = low level is idle state
    SSPCON1bits.SSPM = 0b1010;	// Clk Frequecy (Note: FOSC = 64MHz)
    SSPCON1bits.SSPEN = 1;      // SPI Enable, 1 enables

    // SPI pin I/O setup
    TRISCbits.TRISC3 = OUTPUT;	// SCK
    TRISCbits.TRISC5 = OUTPUT;	// SDO
    TRISDbits.TRISD3 = OUTPUT;	// CS
    CS = 1;

	// driver set up
	intensity = 0x0F;
	driver_write(DISP_MODE, NORMAL);		// leave test mode
	driver_write(SHUTDOWN, SHUTDOWN_OFF);	// leave shutdown mode
	driver_write(INTENSITY, intensity);		// set brightness to highest
    driver_write(SCAN, FULL_SCAN);          // Set scan to all digits
    driver_write(DECODE, NO_DECODE);        // Decoding disabled

	// set displays to display zero
	write_gear(0);
	write_num(0, 2, LEFT);
	write_num(0, 2, RIGHT);

	// intialize states
	cycleStates[LEFT] = CYCLE_L;
	cycleStates[RIGHT] = CYCLE_R;
	holdText[LEFT] = holdText[RIGHT] = TRUE;
	refreshTime[LEFT] = refreshTime[RIGHT] = holdTimer[LEFT] = holdTimer[RIGHT] =
						blinkTimer[LEFT] = blinkTimer[RIGHT] = millis;
	displayStates[LEFT] = OIL_T;
	displayStates[RIGHT] = ENGINE_T;

	ECANInitialize();		// setup ECAN

    // interrupts setup
	INTCONbits.GIE = 1;		// Global Interrupt Enable (1 enables)
	INTCONbits.PEIE = 1;	// Peripheral Interrupt Enable (1 enables)
	RCONbits.IPEN = 0;		// Interrupt Priority Enable (1 enables)

	TRISCbits.TRISC6 = OUTPUT;	// programmable termination
	TERM_LAT = FALSE;

	while(1) {

		// check for change in button state
		if(cycleStates[LEFT] != CYCLE_L & millis - bounceTimer[LEFT] > BOUNCE_TIME) {
			// save new state
			cycleStates[LEFT] = CYCLE_L;
			bounceTimer[LEFT] = millis;
			// only change display if button is low
			if(!cycleStates[LEFT]) {
				if(++displayStates[LEFT] == NUM_CHAN)
					displayStates[LEFT] = 0;
				// put the appropriate text on the displays and
				// get the current time for timing logic
				updateText(LEFT, displayStates);
				holdText[LEFT] = TRUE;
				blinkTimer[LEFT] = holdTimer[LEFT] = millis;
			}
		}
		if(cycleStates[RIGHT] != CYCLE_R  & millis - bounceTimer[RIGHT] > BOUNCE_TIME) {
			cycleStates[RIGHT] = CYCLE_R;
			bounceTimer[RIGHT] = millis;
			if(!cycleStates[RIGHT]) {
				if(++displayStates[RIGHT] == NUM_CHAN)
					displayStates[RIGHT] = 0;
				updateText(RIGHT, displayStates);
				holdText[RIGHT] = TRUE;
                blinkTimer[RIGHT] = holdTimer[RIGHT] = millis;
			}
		}

		// update left and right displays with text or numerical data
		updateDisp(LEFT);
		updateDisp(RIGHT);
		write_gear(gear);

        // radio button
        if(!RADIO) {
            radio_sw[0] = 0x13;
            radio_sw[1] = 0x88;
        }
        else
            *(int *)radio_sw = 0;
#if 0
        // paddle switches
        if(PADDLE_L) {
            paddle_l_sw[0] = 0x13;
            paddle_l_sw[1] = 0x88;
        }
        else
            *(int *)paddle_l_sw = 0;
        if(PADDLE_R) {
            paddle_r_sw[0] = 0x13;
            paddle_r_sw[1] = 0x88;
        }
        else
            *(int *)paddle_r_sw = 0;
#endif
        // DRS override switch
        if(DRS_OVER) {
            drs_over_sw[0] = 0x13;
            drs_over_sw[1] = 0x88;
        }
        else
            *(int *)drs_over_sw = 0;
        // fan override switch
        if(FAN_OVER) {
            fan_over_sw[0] = 0x13;
            fan_over_sw[1] = 0x88;
        }
        else
            *(int *)fan_over_sw = 0;
        // fuel map switch
        if(FUEL_MAP) {
            fuel_map_sw[0] = 0x13;
            fuel_map_sw[1] = 0x88;
        }
        else
            *(int *)fuel_map_sw = 0;

		if(millis - CAN_tmr > CAN_PER) {
			CAN_tmr = millis;
			// send out the first three sampled switches
			ADLmsg[0] = 0x00;
			ADLmsg[1] = 0x00;
			ADLmsg[ADL1] = radio_sw[0];
			ADLmsg[ADL1 + 1] = radio_sw[1];
			ADLmsg[ADL2] = fan_over_sw[0];
			ADLmsg[ADL2 + 1] = fan_over_sw[1];
			ADLmsg[ADL3] = fuel_map_sw[0];
			ADLmsg[ADL3 + 1] = fuel_map_sw[1];
			ECANSendMessage(ADLid, ADLmsg, 8, ECAN_TX_STD_FRAME | ECAN_TX_NO_RTR_FRAME | ECAN_TX_PRIORITY_1);
			// send out first three rotary encoders
			ADLmsg[0] = 0x01;
			ADLmsg[1] = 0x00;
			ADLsample(ADLmsg, ADL4, LAUNCH_ROT);
			ADLsample(ADLmsg, ADL5, TRAC_ROT);
			ADLsample(ADLmsg, ADL6, DRS_ROT);
			ECANSendMessage(ADLid, ADLmsg, 8, ECAN_TX_STD_FRAME | ECAN_TX_NO_RTR_FRAME | ECAN_TX_PRIORITY_1);
		}



	} // end main loop

	return;
}
예제 #13
0
//if there was a bad reading then store the error and shut down the car.
void failure(unsigned char type, unsigned char address, unsigned int intVal, unsigned char charVal)
{
	unsigned int i=0;
	unsigned char action = BALANCEOFF;
	unsigned char send_data[4];
	memcpy_reduced(&(send_data[1]), &intVal);
	send_data[0] = address;
	send_data[3] = charVal;
	//send the message that the car is going to shut down and why
	while(!ECANSendMessage(MASK_MASTER_SHUTDOWN, send_data, 4, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
	//Try to shut the CBS relay off for the module that's out of range. this should not be a problem if the relay fails to shut off.
	while(!ECANSendMessage(MASK_BPS_MASTER | MASK_CBS | ((unsigned int)(address << 2)), &action, 1, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
	printf("Shutting Car Down\n\r");
	printf("Addr = %.2x\n\r",address);
	printf("Volt = %u\n\r",intVal);
	printf("temp = %.2d\n\r",charVal);
	//store the error type (don't bother with type 0(not an error))
	if(type==BPSERR)
	{
		writeByte(LOCATION_ERRTYPE, ((type<<6) & address));
		writeByte(LOCATION_INTVAL0, send_data[1]);
		writeByte(LOCATION_INTVAL1, send_data[2]);
		writeByte(LOCATION_CHARVAL, charVal);
	}
	else if(type == CURRENTERR)
	{
		writeByte(LOCATION_ERRTYPE, (type<<6));
		writeByte(LOCATION_INTVAL0, send_data[1]);
		writeByte(LOCATION_INTVAL1, send_data[2]);
	}
	else if(type == SHUTDOWN)
	{
		writeByte(LOCATION_ERRTYPE, (type<<6));
	}

	//wait very short time for message to get through to LCD and telemetry
	for(i=0; i<1000; ++i);
	
	//shut down the car
	arrayrelay = RELAYOFF;
	mainrelay = RELAYOFF;
	
	//wait for car to shut down (yes it seems pointless until you run it on a power supply)
	//different PWM's for the led to let us know what type of error
	if(switch1 == SWITCHOFF) //switch1 casues data to continue being collected after the relay has been shut off
	{
		if(type==BPSERR){
			while(1){
				led1 = ~led1;
				Delay10KTCYx(0);
			}
		}
		else if(type == CURRENTERR){
			while(1){
				led1 = ~led1;
				Delay10KTCYx(0);
				led1 = ~led1;
				Delay10KTCYx(0);
				Delay10KTCYx(0);
			}
		}
		else if(type == SHUTDOWN){
			while(1){led1 = LEDOFF;}
		}
		else{
			while(1){
				led1 = ~led1;
				for(i=0; i<20; ++i){Delay10KTCYx(0);}
			}
		}
	}
	return;
}
예제 #14
0
void readSlaves(unsigned int *voltageArray, unsigned char *tempArray, unsigned char numModules)
{
	int i = 0, j = 0;
	char messageReceived = 0;
	unsigned char dataReceived[8];	//maximum length that can be recieved
	unsigned char lengthReceived, flagsReceived;
	unsigned long addressReceived = 0;
	unsigned long sendAddress;
	unsigned int receiveTimeoutCounter = 0;
	unsigned int slaveTimeoutCounter = 0;
	unsigned int newVoltage = 0;
	unsigned char newTemp = 0;
	
	for(i=0; i<numModules; ++i)
	{
        unsigned int timeOutCounterJohn = 1000; //how long we wait for a message
		slaveTimeoutCounter = 0;                //how many other messages we get before fail;
		sendAddress = (i << 2) | MASK_BPS_READING;
		//printf("i:%d\r\nadd:%lb\r\n", i, sendAddress);
		while(addressReceived != sendAddress)
		{
			receiveTimeoutCounter = 0;
			//ensure that the 0 transmit buffer is empty
			/*
			while((TXB0CON & 0b10000000) == 0)
			{
				for(j=0; j<100; ++j);
				arrayrelay=~arrayrelay;
				for(j=0; j<100; ++j);
				arrayrelay=~arrayrelay;
			}//*/
			//send the message until it is acknowledged by something
			timeOutCounterJohn = 1000;
			while(!ECANSendMessage((MASK_BPS_MASTER | sendAddress), NULL, 0, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME)  && timeOutCounterJohn) 
			{
				timeOutCounterJohn --;
                for(j=0; j<50; ++j);
				//led1=~led1;
				for(j=0; j<50; ++j);
				//led1=~led1;
			}
			
			//check for a reply from the master acknowleging the message
			while( (!ECANReceiveMessage(&addressReceived, &dataReceived, &lengthReceived, &flagsReceived)) && receiveTimeoutCounter<=RECEIVETIMEOUT  && timeOutCounterJohn) 
			{
                 timeOutCounterJohn--;
            	//	++receiveTimeoutCounter;
				for(j=0; j<100; ++j);
				//led1=~led1;

			//	printf("\tRXcnt: %u\r\n", receiveTimeoutCounter);//need this here for timing
			}
			//printf("RXadd:%lb\r\n", addressReceived);
			
			//*
			++slaveTimeoutCounter;
			if(slaveTimeoutCounter >= SLAVETIMEOUT)
				{printf("Slave Timeout Error\r\n");failure(BPSERR, i, 0x00, 0x00);}//*/
		}
		//check and ensure that three byte has been recieved
		if(lengthReceived == 3)
		{
			//retrieve and store the values for voltage and temperature
			memcpy_reduced(&newVoltage, dataReceived);
			newTemp = dataReceived[2];
			
			//store the new values into their arrays
			voltageArray[i] = newVoltage;
			tempArray[i] = newTemp;
			//print out the values
			GLOBALINTERRUPTS = INTERRUPTDISABLE;
			printf("V[%.2d]=%u\n\r",i, newVoltage);
			printf("T[%.2d]=%.2d\n\r",i, newTemp);
			GLOBALINTERRUPTS = INTERRUPTENABLE;
			//if it is under voltage over voltage or over temperature then shut the car off
			if((newVoltage < CUTOFF_VOLTAGE_LOW) || 
				(newVoltage > CUTOFF_VOLTAGE_HIGH) ||
				(newTemp > CUTOFF_TEMP_HIGH))
			{
				failure(BPSERR, i, newVoltage, newTemp);
			}
		}
		else {printf("Message Corruption Error\r\n");failure(BPSERR, i, 0x00, 0x00);}
	
		//if there was an interrupt, check the current now.
		if(glob_interrupt && switch5 == SWITCHOFF) //switch5 disables current reading
		{
			glob_current=checkcurrent();
			printf("BC=%ld\n\r",glob_current);
			while(!ECANSendMessage((MASK_BPS_MASTER|MASK_BPS_READING), &glob_current, 4, ECAN_TX_STD_FRAME | ECAN_TX_PRIORITY_0 | ECAN_TX_NO_RTR_FRAME));
			glob_interrupt = 0;
		}
	}
	return;
}