// *************************************************************************************************
// @fn          set_value
// @brief       Generic value setting routine
// @param       int32_t  * value						Pointer to value to set
//				uint8_tdigits						Number of digits
//				uint8_t blanks						Number of whitespaces before first valid digit
//				int32_t  limitLow					Lower limit of value
//				int32_t  limitHigh					Upper limit of value
//				uint16_t mode
//				uint8_t segments					Segments where value should be drawn
//				fptr_setValue_display_function1		Value-specific display routine
// @return      none
// *************************************************************************************************
void set_value(int32_t  * value, uint8_t digits, uint8_t blanks, int32_t  limitLow, int32_t  limitHigh, uint16_t mode, uint8_t segments, void (*fptr_setValue_display_function1)(uint8_t segments, uint32_t  value, uint8_t digits, uint8_t blanks, uint8_t disp_mode))
{
	uint8_t update;
	int16_t  stepValue;
	if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
	{
		stepValue=5;
	}
	else
	{
		stepValue=1;
	}
	uint8_t doRound = 0;
	#ifdef CONFIG_STOP_WATCH
	uint8_t stopwatch_state;
	#endif
	uint32_t  val;
	int32_t  orig_val=*value;
	
	// Clear button flags
	button.all_flags = 0;
	
	// Clear blink memory
	clear_blink_mem();
	
	// For safety only - buzzer on/off and button_repeat share same IRQ
	stop_buzzer();
	
	#ifdef CONFIG_STOP_WATCH
	// Disable stopwatch display update while function is active
	stopwatch_state = sStopwatch.state;
	sStopwatch.state = STOPWATCH_HIDE;
	#endif
	
	// Init step size and repeat counter
	sButton.repeats = 0;
	
	// Initial display update
	update = 1;
	
	// Turn on 200ms button repeat function 
	button_repeat_on(200);
	
	// Start blinking with with 2Hz
	set_blink_rate(BIT6 + BIT5);
	
	// Value set loop
	while(1) 
	{
		// Idle timeout: exit function
		if (sys.flag.idle_timeout) break;

		// Button STAR (short) button: exit function
		if (button.flag.star) break;

		// NUM button: exit function and goto to next value (if available)
		if (button.flag.num)
		{
			if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) break;
		}

		// UP button: increase value
		if(button.flag.up)
		{
			// Increase value
			* value = * value + stepValue;
			
			// Check value limits
			if (* value > limitHigh) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) 	* value = limitLow;
				else 																* value = limitHigh;				
					
				// Reset step size to default
				if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
				{
					stepValue=5;
				}
				else
				{
					stepValue=1;
				}
			}

			// Trigger display update
			update = 1;
			
			// Clear button flag
			button.flag.up = 0;
		}
		
		// DOWN button: decrease value
		if(button.flag.down)
		{
			// Decrease value
			* value = * value - stepValue;
			
			// Check value limits
			if (* value < limitLow) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE)	* value = limitHigh;
				else																* value = limitLow;
					
				// Reset step size to default
				if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
				{
					stepValue=5;
				}
				else
				{
					stepValue=1;
				}
			}

			// Trigger display update
			update = 1;

			// Clear button flag	
			button.flag.down = 0;
		}

		
		// When fast mode is enabled, increase step size if Sx button is continuously
		if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE)
		{
			switch (sButton.repeats)
			{
				case 0:			if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE){	stepValue=5;	doRound = 1; }	else {	stepValue=1;	doRound = 0; }	break;
				case 10:		
				case -10:		stepValue = 10;		doRound = 1; 	break;
				case 20:			
				case -20:		stepValue = 100;	doRound = 1; 	break;
				case 30:			
				case -30:		stepValue = 1000;	doRound = 1; 	break;
			}
			
			// Round value to avoid odd numbers on display
			if (stepValue != 1 && doRound == 1)	
			{
				* value -= * value % stepValue;
				doRound = 0;
			}
		}

		// Update display when there is new data
		if (update)
		{
			// Display up or down arrow according to sign of value
			if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS)
			{
				if (* value >= 0)
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
					val = *value;
				}
				else 
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
					val = *value * (-1);
				}
			}
			else
			{
				val = *value;
			}
			
			if((mode & SETVALUE_DISPLAY_SYMBOL) == SETVALUE_DISPLAY_SYMBOL)
			{	
				display_symbol(segments,SEG_ON_BLINK_ON);
				// return when value is changed
				if( orig_val != *value ) break;
			}
			else if( (mode & SETVALUE_SWITCH_ARROWS) == SETVALUE_SWITCH_ARROWS )
			{
				//show up arrow if value is odd
				if( val & 0x1 )
				{
					display_symbol(LCD_SYMB_ARROW_UP,SEG_ON_BLINK_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN,SEG_OFF_BLINK_OFF);
				}
				//show down arrow if value is even
				else
				{
					display_symbol(LCD_SYMB_ARROW_DOWN,SEG_ON_BLINK_ON);
					display_symbol(LCD_SYMB_ARROW_UP,SEG_OFF_BLINK_OFF);
				}
			}
			else
			{
				// Display function can either display value directly, modify value before displaying
				// or display a string referenced by the value
				fptr_setValue_display_function1(segments, val, digits, blanks, SEG_ON_BLINK_ON);
			}

			// Clear update flag
			update = 0;
		}
		
		// Call idle loop to serve background tasks
		idle_loop();
		
	}
	
	//switch symbol
	if((mode & SETVALUE_DISPLAY_SYMBOL) == SETVALUE_DISPLAY_SYMBOL)
	{
		display_symbol(segments,SEG_OFF);
	}
	
	// Set blinking rate to 1Hz and stop
	set_blink_rate(BIT7 + BIT6 + BIT5);
	clear_blink_mem();
	
	// Turn off button repeat function
	button_repeat_off();

	#ifdef CONFIG_STOP_WATCH
	// Enable stopwatch display updates again
	sStopwatch.state = stopwatch_state;
	#endif
}
Example #2
0
// *************************************************************************************************
// @fn          set_value
// @brief       Generic value setting routine
// @param       s32 * value						Pointer to value to set
//				u8digits						Number of digits
//				u8 blanks						Number of whitespaces before first valid digit
//				s32 limitLow					Lower limit of value
//				s32 limitHigh					Upper limit of value
//				u16 mode		
//				u8 segments					Segments where value should be drawn
//				fptr_setValue_display_function1		Value-specific display routine
// @return      none
// *************************************************************************************************
void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, u8 segments, void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks))
{
	u8 update;
	s16 stepValue = 1;
	u8 doRound = 0;
	u32 val;
	
	// Clear button flags
	button.all_flags = 0;
	
	// Clear blink memory
	clear_blink_mem();
	
	// For safety only - buzzer on/off and button_repeat share same IRQ
	stop_buzzer();
	
	// Init step size and repeat counter
	sButton.repeats = 0;
	
	// Initial display update
	update = 1;
	
	// Turn on 200ms button repeat function 
	button_repeat_on(200);
	
	// Start blinking with with 2Hz
	set_blink_rate(BIT6 + BIT5);
	
	// Value set loop
	while(1) 
	{
		// Idle timeout: exit function
		if (sys.flag.idle_timeout) break;

		// STAR (short) button: exit function
		if (button.flag.star) break;

		// NUM button: exit function and goto to next value (if available)
		if (button.flag.num)
		{
			if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) break;
		}

		// UP button: increase value
		if(button.flag.up)
		{
			// Increase value
			* value = * value + stepValue;
			
			// Check value limits
			if (* value > limitHigh) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) 	* value = limitLow;
				else 																* value = limitHigh;				
					
				// Reset step size to default
				stepValue = 1;	
			}

			// Trigger display update
			update = 1;
			
			// Clear button flag
			button.flag.up = 0;
		}
		
		// DOWN button: decrease value
		if(button.flag.down)
		{
			// Decrease value
			* value = * value - stepValue;
			
			// Check value limits
			if (* value < limitLow) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE)	* value = limitHigh;
				else																* value = limitLow;
					
				// Reset step size to default
				stepValue = 1;	
			}

			// Trigger display update
			update = 1;

			// Clear button flag	
			button.flag.down = 0;
		}

		
		// When fast mode is enabled, increase step size if Sx button is continuously
		if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE)
		{
			switch (sButton.repeats)
			{
				case 0:			stepValue = 1;		doRound = 0; 	break;
				case 10:		
				case -10:		stepValue = 10;		doRound = 1; 	break;
				case 20:			
				case -20:		stepValue = 100;	doRound = 1; 	break;
				case 30:			
				case -30:		stepValue = 1000;	doRound = 1; 	break;
			}
			
			// Round value to avoid odd numbers on display
			if (stepValue != 1 && doRound == 1)	
			{
				* value -= * value % stepValue;
				doRound = 0;
			}
		}

		// Update display when there is new data
		if (update)
		{
			// Display up or down arrow according to sign of value
			if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS)
			{
				if (* value >= 0)
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
					val = *value;
				}
				else 
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
					val = *value * (-1);
				}
			}
			else
			{
				val = *value;
			}

			// Display function can either display value directly, modify value before displaying 
			// or display a string referenced by the value
			fptr_setValue_display_function1(segments, val, digits, blanks);

			// Clear update flag
			update = 0;
		}
		
		// Call idle loop to serve background tasks
		idle_loop();
		
	}
	
	// Clear up and down arrows
	display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
	display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
	
	// Set blinking rate to 1Hz and stop
	set_blink_rate(BIT7 + BIT6 + BIT5);
	clear_blink_mem();
	
	// Turn off button repeat function
	button_repeat_off();
}
Example #3
0
int main (void)
{	
	int tmp,i,res;
	CLKPR = 0x80;  CLKPR = 0x00;  // Clock prescaler Reset

/*-----------------------------------------------------------------*
 *------------------------- Gear buttoms setup---------------------*
 *-----------------------------------------------------------------*/
	DDRC&=~(1<<PC7); // Neutral
	PORTC |= (1<<PC7); // Neutral pull-up
	DDRE&=~(1<<PE6); // Knap1 
	DDRE&=~(1<<PE7); // Knap2

	/* Buttoms interrupt */
	EICRB |= (1<<ISC71|1<<ISC70|1<<ISC61|1<<ISC60); /* Rising edge */
	EIMSK |= (1<<INT7 | 1<<INT6);


	uint8_t test_rx[8];

	int8_t data;
	char streng[10];

	// Recieve buffer
	st_cmd_t msg;

//  Init CAN, UART, I/O
	init();
	uartinit();
	sendtekst("UART initialized\n\r");
	TWI_init();
	sendtekst("TWI initialized\n\r");

	sei();		/* Interrupt enable */
	sendtekst("Interrupt enabled\n\r");
/*-----------------------------------------------------------------*
 *----------------------------Display setup -----------------------*
 *-----------------------------------------------------------------*/

	/* Set blink rates */
	set_blink_rate(LED0_7_ADDR, LED_BLINK1, 20, 100);
	set_blink_rate(LED0_7_ADDR, LED_BLINK2, 0, RPM_LED_DUTYCYCLE*2.56);

	set_blink_rate(LED8_15_ADDR, LED_BLINK1, (1.0/RPM16_RATE)*252, RPM16_DUTYCYCLE*2.56);
	set_blink_rate(LED8_15_ADDR, LED_BLINK2, 0, RPM_LED_DUTYCYCLE*2.56);

	set_blink_rate(SEG_ADDR, LED_BLINK1, 20, 100);
	set_blink_rate(SEG_ADDR, LED_BLINK2, 0, SEG_DUTYCYCLE*2.56);

	set_blink_rate(LED_BUTTONS_ADDR, LED_BLINK1, 20, 100);
	set_blink_rate(LED_BUTTONS_ADDR, LED_BLINK2, 0, SEG_DUTYCYCLE*2.56);


/*-----------------------------------------------------------------*
 *----------------------------CAN interrupt setup -----------------*
 *-----------------------------------------------------------------*/
	Can_sei();		/* Enable general can interrupt */
	Can_set_tx_int();	/* Enable can tx interrupt */
	Can_set_rx_int();	/* Enable can rx interrupt */

	/*
	 *	Kode til hurtig test af can 
	 */
	sendtekst("Config 3 mailboxes for rpm_msgid...\n\r");
	msg.id.std = rpm_msgid;
	msg.dlc = 8;
	res = can_config_rx_mailbox(&msg, 3);
	if (res == CAN_CMD_ACCEPTED) {
		sendtekst("SUCCESS\n\r");
	} else {
		sendtekst("FAIL\n\r");
	}	
    	// --- Init variables

	/* Init user led 0 & 1 */
	DDRB |= (1<<PB6 | 1<<PB5);
	PORTB |= (1<<PB6 | 1<<PB5);

	sendtekst("Beep\n\r");
	display_test();
    
    params.GearEst = 0;

	char dataout[] = {gear,0};

	while (1) {
		_delay_ms(20);

		/* Display selected parameter */
		if (mode == RPM_MODE) {		
			set_rpm(params.rpm, LED_ON);
		} else if (mode == VOLTAGE_MODE) {
			set_voltage(params.batteryV, LED_ON);
		} else if (mode == WATER_TEMP_MODE) {
			set_water_temp(params.waterTemp, LED_ON);
		}

		// Geat buttons to CAN
		dataout[1] = 0;
		/* Format buttom states for sending */ 
		dataout[1] |= (params.GearButDown*GEARDOWNBUT | 
					GEARUPBUT*params.GearButUp | 
					params.GearButNeutral*GEARNEUBUT);

		/* Send buttom states */
		if(dataout[1] != 0) {
			// Hack, sender gearskiftesignal et par gange, sådan at det går igennem
			// Symptombehandling, sygdommen skal kureres...
			if (dataout[1] & (GEARDOWNBUT) == GEARDOWNBUT)
				indi_leds_state |= (LED_BLINK2<<LED_BUTTON_1);
			if (dataout[1] & (GEARUPBUT) == GEARUPBUT)
				indi_leds_state |= (LED_BLINK2<<LED_BUTTON_1);
		

			set_leds(LED_BUTTONS_ADDR, indi_leds_state);
			for(j=0;j<1;j++){
				can_send_non_blocking(gear_msgid, dataout, 2);
				_delay_ms(5);
			}
			indi_leds_state &= ~(LED_BLINK2<<LED_BUTTON_2);
			indi_leds_state &= ~(LED_BLINK2<<LED_BUTTON_1);
			set_leds(LED_BUTTONS_ADDR, indi_leds_state);

		}
		/* Clear buttom states */
		params.GearButDown = 0;
		params.GearButUp = 0;
		params.GearButNeutral = 0;

		/* Display bottons code */
		buttons_state = get_buttons(LED_BUTTONS_ADDR) & (BUTTON1 | BUTTON2);
		if (buttons_state == 2) {
			indi_leds_state |= (LED_BLINK2<<LED_BUTTON_1);
			indi_leds_state &= ~(LED_BLINK2<<LED_BUTTON_2);
			mode = VOLTAGE_MODE;
		} else if (buttons_state == 1) {
			indi_leds_state |= (LED_BLINK2<<LED_BUTTON_2);
			indi_leds_state &= ~(LED_BLINK2<<LED_BUTTON_1);
			mode = WATER_TEMP_MODE;
		} else if (buttons_state == 0) {
			indi_leds_state |= (LED_BLINK2<<LED_BUTTON_1 | LED_BLINK2<<LED_BUTTON_2);
		} else {
			indi_leds_state &= ~(LED_BLINK2<<LED_BUTTON_1 | LED_BLINK2<<LED_BUTTON_2);
			mode = RPM_MODE;
		}

		/* Indicator for water temp */
		if (params.waterTemp <= WATER_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI1);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI4);
		} else if (params.waterTemp > WATER_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI4);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI1);
		}

		/* Indicator for batt ok */
		if (params.batteryV <= VOLTAGE_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI2);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI5);
		} else if (params.batteryV > VOLTAGE_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI5);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI2);
		}
		
		/* Indicator for oil pressure ok */
		if (params.oilPressure <= OILPRESS_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI3);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI6);
		} else if (params.oilPressure > OILPRESS_OK) {
			indi_leds_state |= (LED_BLINK2<<LED_INDI6);
			indi_leds_state &= ~(LED_BLINK2<<LED_INDI3);
		}

		/* Indicator for Gear */
		if (params.GearNeutral < 0) {
			SEG_N(LED_ON);
		} else {
			if (params.GearEst > 6) {
				SEG_OFF();
			} else {
				switch (params.GearEst) {
                    case 0:
						SEG_N(LED_ON);
						break;
					case 1:
						SEG_1(LED_ON);
						break;
					case 2:
						SEG_2(LED_ON);
						break;
					case 3:
						SEG_3(LED_ON);
						break;
					case 4:
						SEG_4(LED_ON);
						break;
					case 5:
						SEG_5(LED_ON);
						break;
					case 6:
						SEG_6(LED_ON);
						break;
					default:
						break;

				}
			}
		}


/*		if (params.GearNeutral == 0) {
			SEG_OFF();
		} else if (params.GearNeutral > 0) {
			SEG_N(LED_BLINK2);
		}
*/

		/* Set indicator leds */
		set_leds(LED_BUTTONS_ADDR, indi_leds_state);
			
/*		itoa(params.batteryV, streng, 10);*/
/*		sendtekst(streng);*/
/*		sendtekst("\n\r");		*/
		PORTB ^= (1<<PB6);
	}
	return 0;
}