int main(void)
{
    port_init();
	serialport_init();
	timer_init();
	tempSensor_init();
	//alpha_init();
	
	// activate interrupts
	sei();
	
	uint8_t i,j;						// multi used index variables
	uint16_t k;
	
	uint8_t messageCtr = 0;				// message counter for automatic messages 
	
	CARRIAGE aDataSet;					// a data set used for communication
	
	uint8_t temperature[24];			// the temperatures, actual only 0-7 are in use
	uint8_t spare_temperature[8];		// the spare values for the aida values (actual not in use)
	uint8_t spare_temperatureTimer = 5; // timeout timer for AIDA temperature (use spare values until values are older then 4 seconds)
	
	uint16_t literPerHour = 0;
		
	CHANNELDATA channel_data[NUMBEROFCHANNELS];		// the permanent data of the 4 channels (fan 1-3 and analog)
	CHANNELSTATUS channel_status[NUMBEROFCHANNELS];	// the actual status of the channels
	
	LEDDATA led_data;					// data for the led channels
	uint16_t ledCtr = 0;				// a rotary counter value for led sweep calculation, incremented every 100 ms
	
	ALERTDATA alert_data;				// data for alert
	ALERTSTATUS alert_status;			// actual status
	
	uint8_t time[3] = {0,0,0};			// = {h,m,s}
	uint16_t pcStatus[4] = {0,0,0,0};	// = {CPU_CLK,CPU%,GPU%,RAM%}
	
	uint16_t pulsePerLiter;
	
	
	if (eeprom_read_word(&eeprom_eepromVersionChecker) != EEPROMVERSION_BITS)			// EEPROM is not OK
	{		
		
		// serialport_printf("#EEPROM FAILED, START TO OVERWRITE IT!#\r");
		
		for (j=0;j<NUMBEROFCHANNELS;j++)
		{
			for (i=0;i<sizeof(CHANNELDATA);i++)
			{
				eeprom_write_byte(((uint8_t *)&eeprom_channel_data[j])+i,pgm_read_byte(((uint8_t *)&default_channel_data)+i));
			}			
		}
		
		// serialport_printf("#CHANNELS COMPLETE#\r");
				
		for (i=0;i<8;i++)
		{
			eeprom_write_byte((&eeprom_spare_temperature[i]),pgm_read_byte(&default_spare_temperature[i]));
		}
		
		// serialport_printf("#SPARE TEMPERATURES COMPLETE#\r");
		
		for (i=0;i<sizeof(LEDDATA);i++)
		{
			eeprom_write_byte(((uint8_t *)&eeprom_led_data)+i,pgm_read_byte(((uint8_t *)&default_led_data)+i));
		}
		
		// serialport_printf("#LED COMPLETE#\r");
		
		for (i=0;i<sizeof(ALERTDATA);i++)
		{
			eeprom_write_byte(((uint8_t *)&eeprom_alert_data)+i,pgm_read_byte(((uint8_t *)&default_alert_data)+i));
		}
		
		// serialport_printf("#ALERT COMPLETE#\r");
		
		eeprom_write_word(&eeprom_pulsePerLiter,pgm_read_word(&default_pulsePerLiter));
		
		// serialport_printf("#PULSEPERLITER COMPLETE#\r");
		
		for (k=0;k<sizeof(ALPHANUMERIC);k++)
		{
			eeprom_write_byte(((uint8_t *)&eeprom_alphaDisplay)+k,pgm_read_byte(((uint8_t *)&default_alphaDisplay)+k));
		}
		
		// serialport_printf("\r#DISPLAY COMPLETE#\r");
		
		eeprom_write_word(&eeprom_eepromVersionChecker,EEPROMVERSION_BITS);
		
		// serialport_printf("#EEPROMVERSION COMPLETE#\r");
		// serialport_printf("#EEPROM OVERRIDE COMPLETE, START#\r");
	}
	
	
	pulsePerLiter = eeprom_read_word(&eeprom_pulsePerLiter);	// impulses per liter of the flow meter
	timer_setImpulsePerLiter(pulsePerLiter);							// inform the timer
	
	//ALPHANUMERIC alphaDisplay;
	//uint8_t screenIndex = 0;
	//uint8_t screenCountdown;
	//uint8_t screenOverlayMessageCountdown = 0;
	//
	//uint8_t switch1_ctr = 0;
	//uint8_t switch2_ctr = 0;
	//
	//uint8_t buzzerEnable = 1;
	
	// read the EEPROM
	eeprom_read_block((void*)channel_data, (const void*)eeprom_channel_data, (NUMBEROFCHANNELS*sizeof(CHANNELDATA)));
	eeprom_read_block((void*)spare_temperature, (const void*)eeprom_spare_temperature, 8);
	eeprom_read_block((void*)&led_data, (const void*)&eeprom_led_data, sizeof(LEDDATA));
	eeprom_read_block((void*)&alert_data, (const void*)&eeprom_alert_data, sizeof(ALERTDATA));
	//eeprom_read_block((void*)&alphaDisplay, (const void*)&eeprom_alphaDisplay, sizeof(ALPHANUMERIC));
	//timer_setPwm(BACKLIGHT,alphaDisplay.backlight);
	//alpha_setContrast(alphaDisplay.contrast);
	//screenCountdown = alphaDisplay.screen[0];	
	
	
	for (i=0;i<NUMBEROFCHANNELS;i++)
	{
		channel_status[i].startupTimer = channel_data[i].startupTime;
		channel_status[i].status = startup;		
	}
	
		
	
	
	//#ifdef REV2_1
		//alpha_displayOverlayMessage("    ConFLiCT                    FW: C0.3 HW: 2.1");
	//#endif
	//#ifdef REV2_2
		//alpha_displayOverlayMessage("    ConFLiCT                    FW: C0.3 HW: 2.2"); 
	//#endif	
	//screenOverlayMessageCountdown = 10; 
		
	while(1)						// main loop
    {
        		
		// use spare temperatures if aida temperatures are to old
		if (spare_temperatureTimer > 4)
		{
			for (i=0;i<8;i++)
			{
				temperature[i+16] = spare_temperature[i];
			}
		}
				
		alert_status.overtemp = 0;				// reset the overtemp alert 
		
		// calculate the channel power
		for (i=0;i<NUMBEROFCHANNELS;i++)
		{	
					
			if (channel_data[i].automaticMode)		// automatic mode
			{
				uint8_t cooling = 0;			// temporary cooling value
				uint8_t d1, d2;					// temporary variable for calculation
				for (j=0;j<24;j++)
				{
					if ((temperature[j] >= channel_data[i].minTemp[j]) && (temperature[j] <= channel_data[i].maxTemp[j])) // temperature is between min and max
					{
						d1 = 100 / (channel_data[i].maxTemp[j] - channel_data[i].minTemp[j]);	// calculate cooling value
						d2 = (temperature[j] - channel_data[i].minTemp[j]) * d1;
						if (d2 > cooling)	// save the highest cooling value	
						{
							cooling = d2;
						}						
					}
					if (temperature[j] > channel_data[i].maxTemp[j])	// a temperature over maximum! o.O
					{
						// over temperature
						if (alert_data.overtempEnable)
						{
							alert_status.overtemp = 1;
						}					
						cooling = 100;
					}				
				}
				
				switch (channel_status[i].status)						// check the status
				{
					case off:		
						channel_status[i].power = 0;					// turn it off
						if (channel_data[i].stopEnable)					// off allowed
						{
							if (cooling > channel_data[i].threshold)	// if cooling is higher then threshold
							{
								channel_status[i].status = startup;		// start the channel and reset the startup timer
								channel_status[i].startupTimer = channel_data[i].startupTime;
							}							
						}
						else                                            // off is not allowed (anymore)
						{
							channel_status[i].status = startup;			// start the channel and reset the startup timer
							channel_status[i].startupTimer = channel_data[i].startupTime;
						}
						break;
					
					case startup:										
						channel_status[i].power = 100;					// 100 % for startup
						break;
					
					case on:
						if ((cooling == 0) && (channel_data[i].stopEnable == 1))	// if stop is enabled and no cooling needed
						{
							channel_status[i].status = off;				// turn it off
						}
						// calculate the power value out off the minimum value and the cooling value
						channel_status[i].power = (uint8_t)((((uint16_t)(100-channel_data[i].minimumPower))*cooling)/100 + channel_data[i].minimumPower);
						break;
				}				
			}
			 
			else								// manual mode
			{
				switch (channel_status[i].status)					// check the status
				{
					case off:						
						channel_status[i].power = 0;				// turn it off
						if (channel_data[i].manualPower > 0)		
						{
							channel_status[i].status = startup;		// start the channel and reset the startup timer
							channel_status[i].startupTimer = channel_data[i].startupTime;
						}					
						break;
					
					case startup:
						channel_status[i].power = 100;				// 100 % for startup
						break;
						
					case on:
						channel_status[i].power = channel_data[i].manualPower;
						if (channel_data[i].manualPower == 0)		// if no power, go to off
						{
							channel_status[i].status = off;
						}
						break;						
				}						
			}	
					
		}
		
		alert_status.fanblock = 0;		// reset the fan block status
		
		// exchange channel with hardware timer
		for (i=0;i<NUMBEROFCHANNELS;i++)
		{
			timer_setPwm(i,channel_status[i].power);
			channel_status[i].rpm = timer_getRpm(i);
			if (channel_status[i].status == on && channel_status[i].rpm == 0 && alert_data.fanblockEnable && i != 3)
			{
				alert_status.fanblock = 1;		// fan is blocked or not started correctly
			}			
		}
		
		// get liter per hour
		literPerHour = timer_getLH();
		if (literPerHour < alert_data.minWaterFlow)
		{
			alert_status.lowWaterFlow = 1;
		}
		else
		{
			alert_status.lowWaterFlow = 0;
		}
			
		
		
		// led exchange and calculating
		switch (led_data.mode)		
		{
			case 0:		// manual mode
				timer_setPwm(LED_RED,led_data.manualPower[0]);
				timer_setPwm(LED_GREEN,led_data.manualPower[1]);
				timer_setPwm(LED_BLUE,led_data.manualPower[2]);
				break;
				
			case 1:
				// Do calculation with ledCtr, timer_setPWM(LED_X,value), and local variables only!
				if (ledCtr < 100)
				{
					timer_setPwm(LED_RED,ledCtr);
					timer_setPwm(LED_GREEN,0);
					timer_setPwm(LED_BLUE,0);
				} 
				else if(ledCtr < 200)
				{
					timer_setPwm(LED_RED,200-ledCtr);
					timer_setPwm(LED_GREEN,0);
					timer_setPwm(LED_BLUE,0);
				}
				else if (ledCtr < 300)
				{
					timer_setPwm(LED_GREEN,ledCtr-200);
					timer_setPwm(LED_RED,0);
					timer_setPwm(LED_BLUE,0);
				}
				else if (ledCtr < 400)
				{
					timer_setPwm(LED_GREEN,400-ledCtr);
					timer_setPwm(LED_RED,0);
					timer_setPwm(LED_BLUE,0);
				}
				else if (ledCtr < 500)
				{
					timer_setPwm(LED_BLUE,ledCtr-400);
					timer_setPwm(LED_RED,0);
					timer_setPwm(LED_GREEN,0);
				}
				else if (ledCtr < 600)
				{
					timer_setPwm(LED_BLUE,600-ledCtr);
					timer_setPwm(LED_RED,0);
					timer_setPwm(LED_GREEN,0);
				} 
				else
				{
					ledCtr = 0;
				}
				break;
				
			default:	// wrong mode, red led on
				timer_setPwm(LED_BLUE,0);
				timer_setPwm(LED_GREEN,0);
				timer_setPwm(LED_RED,100);
				break;				
		} 
		
				
			
		
		// each 524ms
		if (timer_524ms())
		{			
			// decrement the channel startup timers
			for (i=0;i<NUMBEROFCHANNELS;i++)
			{
				if (channel_status[i].startupTimer > 1)
				{
					channel_status[i].startupTimer--;
				}
				if (channel_status[i].startupTimer == 1)
				{
					channel_status[i].startupTimer = 0;
					channel_status[i].status = on;		// go to on if startup time is over
				}
			}
			
			// increment the spare temperature timer
			if (spare_temperatureTimer < 255)
			{
				spare_temperatureTimer ++;
			}
			
			// beeper
			//if ((alert_status.fanblock || alert_status.lowWaterFlow || alert_status.overtemp) && buzzerEnable)
			//{
				//// toggle beeper
				//PORTR_OUTTGL = 1;
			//} 
			//else
			//{
				//// turn beeper off
				//PORTR_OUTCLR = 1;
			//}
			
			
			// display
			//screenCountdown --;						
			//if (screenCountdown == 0)
			//{
				//screenIndex ++;
				//if (alphaDisplay.screen[screenIndex] == 0)		// screen is not available
				//{
					//screenIndex = 0;		// go to first screen					
				//} 
				//screenCountdown = alphaDisplay.screen[screenIndex];				
			//}
			//if (screenOverlayMessageCountdown == 0)
			//{
				//// if no alert is active, show normal display content
				//if (alert_status.fanblock == 0 && alert_status.lowWaterFlow == 0 && alert_status.overtemp == 0)
				//{
					//alpha_updateScreen(screenIndex,alphaDisplay.content,temperature,time,pcStatus,&literPerHour,channel_status);
				//}
				//else // else show the alert
				//{
					//alpha_displayAlert(alert_status);
				//}
			//} 
			//else
			//{
				//screenOverlayMessageCountdown--;
			//}
			
				
		}
			
		// each 100ms
		if (timer_100ms())
		{
			// get the temperatures
			for (i=0;i<16;i++)
			{
				temperature[i] = tempSensor_getTemp(i);		// read out up to 8 NTC-Sensors and 8 1-Wire sensors
			}
						
			
			ledCtr++;
			
			// check switch 1, left button
			//if (SWITCH1)
			//{
				//if (switch1_ctr < 255)
				//{
					//switch1_ctr++;
				//}
			//}
			//else
			//{
				//switch1_ctr = 0;
			//}
			//
			//if (switch1_ctr == 2)
			//{
				//if (buzzerEnable)
				//{
					//buzzerEnable = 0;
					//// turn beeper off
					//PORTR_OUTCLR = 1;
					//alpha_displayOverlayMessage("buzzer disabled");
				//}
				//else
				//{
					//buzzerEnable = 1;
					//alpha_displayOverlayMessage("buzzer enabled");
				//}
				//screenOverlayMessageCountdown = 2;				
			//}
			
			// check the next button (switch 2, right button)
			//if (SWITCH2)
			//{				
				//if (switch2_ctr < 255)
				//{					
					//switch2_ctr++;					
				//}		
			//}
			//else
			//{
				//switch2_ctr = 0;
			//}
			//
			//
			//// change display content if button 2 is short pressed or every 1 second pressed
			//if (switch2_ctr == 10)
			//{
				//switch2_ctr = 1;
			//}
			//
			//if (switch2_ctr == 1)
			//{
				//screenIndex ++;
				//if (alphaDisplay.screen[screenIndex] == 0)		// screen is not available
				//{
					//screenIndex = 0;		// go to first screen
				//}
				//screenCountdown = alphaDisplay.screen[screenIndex];
				//// if no alert is active, show normal display content
				//if (alert_status.fanblock == 0 && alert_status.lowWaterFlow == 0 && alert_status.overtemp == 0)
				//{
					//alpha_updateScreen(screenIndex,alphaDisplay.content,temperature,time,pcStatus,&literPerHour,channel_status);
				//}
			//}
			
			
			
			// send some actual information to the PC
			// every 100 ms an other of these messages 
			messageCtr++;
			aDataSet.dA = SERIALPORT_DATA;
			switch (messageCtr)
			{
				case 1:		// temperatures
					aDataSet.id = 30;					
					for (i=0;i<24;i++)
					{
						aDataSet.index = i + 1;
						aDataSet.data = temperature[i];
						serialport_writeCarriage(&aDataSet);
					}
					break;
			
				case 2:		// alerts
					aDataSet.id = 50;
					aDataSet.index = 1;
					aDataSet.data = alert_status.overtemp;
					serialport_writeCarriage(&aDataSet);
					aDataSet.index = 2;
					aDataSet.data = alert_status.fanblock;
					serialport_writeCarriage(&aDataSet);
					aDataSet.index = 3;
					aDataSet.data = alert_status.lowWaterFlow;
					serialport_writeCarriage(&aDataSet);
					break;
			
				case 3:		// water flow
					aDataSet.id = 60;
					aDataSet.index = 1;
					aDataSet.data = literPerHour;
					serialport_writeCarriage(&aDataSet);
					break;
			
				case 4:		// RPM of channels
					aDataSet.id = 61;
					for (i= 0;i<4;i++)
					{
						aDataSet.index = i + 1;
						aDataSet.data = channel_status[i].rpm;
						serialport_writeCarriage(&aDataSet);
					}
					break;
			
				case 5:		// power values
					aDataSet.id = 62;
					aDataSet.dA = SERIALPORT_DATA;
					for (i= 0;i<NUMBEROFCHANNELS;i++)
					{
						aDataSet.index = i + 1;
						aDataSet.data = channel_status[i].power;
						serialport_writeCarriage(&aDataSet);
					}
					messageCtr = 0;
					break;			
			}				
		}			
		
		
		// check for received carriages
		if (serialport_getLastCarriage(&aDataSet) == 0)								// new carriage received
		{
						
			if (aDataSet.dA == SERIALPORT_DATA)			// new data
			{
				switch(aDataSet.id)
				{
					case 01:							// reset
						if (aDataSet.index == 170 && aDataSet.data == 85)
						{
							cli();						// disable interrupts
							wdt_reset();				// reset via watchdog
							_delay_ms(1);				// wait until reset occurs
						}						
						break;
						
					case 30:							// temperatures from AIDA or other PC software
						temperature[aDataSet.index-1] = aDataSet.data;
						spare_temperatureTimer = 0;
						break;
					
					case 11:							// minimum temperatures channel 0
						channel_data[0].minTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[0].minTemp[aDataSet.index-1], channel_data[0].minTemp[aDataSet.index-1]);
						break;
					
					case 21:							// maximum temperatures channel 0
						channel_data[0].maxTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[0].maxTemp[aDataSet.index-1], channel_data[0].maxTemp[aDataSet.index-1]);
						break;
					
					case 12:							// minimum temperatures channel 1
						channel_data[1].minTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[1].minTemp[aDataSet.index-1], channel_data[1].minTemp[aDataSet.index-1]);
						break;
					
					case 22:							// maximum temperatures channel 1
						channel_data[1].maxTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[1].maxTemp[aDataSet.index-1], channel_data[1].maxTemp[aDataSet.index-1]);
						break;
						
					case 13:							// minimum temperatures channel 2
						channel_data[2].minTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[2].minTemp[aDataSet.index-1], channel_data[2].minTemp[aDataSet.index-1]);
						break;
					
					case 23:							// maximum temperatures channel 2
						channel_data[2].maxTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[2].maxTemp[aDataSet.index-1], channel_data[2].maxTemp[aDataSet.index-1]);
						break;	
						
					case 14:							// minimum temperatures channel 3
						channel_data[3].minTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[3].minTemp[aDataSet.index-1], channel_data[3].minTemp[aDataSet.index-1]);
						break;
					
					case 24:							// maximum temperatures channel 3
						channel_data[3].maxTemp[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[3].maxTemp[aDataSet.index-1], channel_data[3].maxTemp[aDataSet.index-1]);
						break;
						
					case 31:							// spare temperatures
						spare_temperature[aDataSet.index-17] = aDataSet.data;
						eeprom_update_byte(&eeprom_spare_temperature[aDataSet.index-17], spare_temperature[aDataSet.index-17]);
						break;	
						
					case 40:							// time
						time[aDataSet.index-1] = aDataSet.data;
						break;
					
					case 41:							// PC information
						pcStatus[aDataSet.index-1] = aDataSet.data;
						break;
					
					case 51:							// alert enable
						if (aDataSet.index == 1)
						{
							alert_data.overtempEnable = aDataSet.data;
							eeprom_update_byte(&eeprom_alert_data.overtempEnable, alert_data.overtempEnable);
						} 
						else if (aDataSet.index == 2)
						{
							alert_data.fanblockEnable = aDataSet.data;
							eeprom_update_byte(&eeprom_alert_data.fanblockEnable, alert_data.fanblockEnable);
						}
						break;
					
						
					case 70:							// Pulse per liter of flowMeter
						if (aDataSet.index == 1)
						{
							pulsePerLiter = aDataSet.data;
							timer_setImpulsePerLiter(pulsePerLiter);
							eeprom_update_word(&eeprom_pulsePerLiter, pulsePerLiter);
						}
						else if (aDataSet.index == 2)
						{
							alert_data.minWaterFlow = aDataSet.data;
							eeprom_update_word(&eeprom_alert_data.minWaterFlow, alert_data.minWaterFlow);
						}
						break;
					
					case 71:							// manual power
						channel_data[aDataSet.index-1].manualPower = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].manualPower, channel_data[aDataSet.index-1].manualPower);
						break;
						
					case 72:							// startup times
						if (aDataSet.data == 0)
						{
							channel_data[aDataSet.index-1].startupTime = 1;							
						} 
						else
						{
							channel_data[aDataSet.index-1].startupTime = aDataSet.data;
						}
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].startupTime, channel_data[aDataSet.index-1].startupTime);
						break;
					
					case 73:							// minimum power
						channel_data[aDataSet.index-1].minimumPower = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].minimumPower, channel_data[aDataSet.index-1].minimumPower);
						break;
						
					case 74:							// automatic mode
						channel_data[aDataSet.index-1].automaticMode = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].automaticMode, channel_data[aDataSet.index-1].automaticMode);
						break;
						
					case 75:							// stop enable
						channel_data[aDataSet.index-1].stopEnable = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].stopEnable, channel_data[aDataSet.index-1].stopEnable);
						break;
						
					case 76:							// threshold
						channel_data[aDataSet.index-1].threshold = aDataSet.data;
						eeprom_update_byte(&eeprom_channel_data[aDataSet.index-1].threshold, channel_data[aDataSet.index-1].threshold);
						break;
						
					case 77:							// backlight and contrast
						//if (aDataSet.index == 1)
						//{
							//alphaDisplay.backlight = aDataSet.data;
							//timer_setPwm(BACKLIGHT,alphaDisplay.backlight);
							//eeprom_update_byte(&eeprom_alphaDisplay.backlight, alphaDisplay.backlight);
						//}
						//else if (aDataSet.index == 2)
						//{
							//alphaDisplay.contrast = aDataSet.data;
							//alpha_setContrast(alphaDisplay.contrast);
							//eeprom_update_byte(&eeprom_alphaDisplay.contrast, alphaDisplay.contrast);
						//}
						break;
					
					case 78:							// led mode
						led_data.mode = aDataSet.data;
						eeprom_update_byte(&eeprom_led_data.mode, led_data.mode);
						ledCtr = 0;
						break;
						
					case 79:							// led manual power
						led_data.manualPower[aDataSet.index-1] = aDataSet.data;
						eeprom_update_byte(&eeprom_led_data.manualPower[aDataSet.index-1], led_data.manualPower[aDataSet.index-1]);
						break;
						
					case 80:							// display content
						//alphaDisplay.content[aDataSet.index-1] = aDataSet.data;
						//eeprom_update_byte(&eeprom_alphaDisplay.content[aDataSet.index-1], alphaDisplay.content[aDataSet.index-1]);
						break;
						
					case 81:							// display screens
						//alphaDisplay.screen[aDataSet.index-1] = aDataSet.data;
						//eeprom_update_byte(&eeprom_alphaDisplay.screen[aDataSet.index-1], alphaDisplay.screen[aDataSet.index-1]);
						break;												
				}				
			}
			
			if (aDataSet.dA == SERIALPORT_ASK)			// new ask
			{
				aDataSet.dA = SERIALPORT_DATA;			// return always data
				switch(aDataSet.id)
				{
					case 0:								// ask for everything
						aDataSet.id = 02;
						aDataSet.index = 1;
						aDataSet.data = FIRMWAREVERSION;
						serialport_writeCarriage(&aDataSet);
						aDataSet.index = 2;
						aDataSet.data = EEPROMVERSION;
						serialport_writeCarriage(&aDataSet);
						for (i=0;i<24;i++)
						{
							aDataSet.id = 11;			// 11
							aDataSet.index = i+1;
							aDataSet.data = channel_data[0].minTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 21;			// 21
							aDataSet.data = channel_data[0].maxTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 12;			// 12
							aDataSet.data = channel_data[1].minTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 22;			// 22
							aDataSet.data = channel_data[1].maxTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 13;			// 13
							aDataSet.data = channel_data[2].minTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 23;			// 23
							aDataSet.data = channel_data[2].maxTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 14;			// 14
							aDataSet.data = channel_data[3].minTemp[i];
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 24;			// 24
							aDataSet.data = channel_data[3].maxTemp[i];
							serialport_writeCarriage(&aDataSet);							
						}
						aDataSet.id = 31;				// 31
						for (i=0;i<8;i++)
						{
							aDataSet.index = i+17;
							aDataSet.data = spare_temperature[i];
							serialport_writeCarriage(&aDataSet);
						}						
						aDataSet.id = 32;				// 32
						aDataSet.index = 1;
						aDataSet.data = tempSensor_getOneWireAmount();
						serialport_writeCarriage(&aDataSet);												
						aDataSet.id = 33;				// 33
						for (i=0;i<(8*tempSensor_getOneWireAmount());i++)
						{
							aDataSet.index = i+1;
							aDataSet.data = tempSensor_getOneWireID(i);
							serialport_writeCarriage(&aDataSet);
						}						
						aDataSet.id = 51;				// 51
						aDataSet.index = 1;
						aDataSet.data = alert_data.overtempEnable;
						serialport_writeCarriage(&aDataSet);
						aDataSet.index = 2;
						aDataSet.data = alert_data.fanblockEnable;
						serialport_writeCarriage(&aDataSet);
						aDataSet.id = 70;				// 70
						aDataSet.index = 1;
						aDataSet.data = pulsePerLiter;
						serialport_writeCarriage(&aDataSet);
						aDataSet.index = 2;
						aDataSet.data = alert_data.minWaterFlow;
						serialport_writeCarriage(&aDataSet);
						for (i=0;i<4;i++)
						{
							aDataSet.id = 71;				// 71
							aDataSet.index = i+1;
							aDataSet.data = channel_data[i].manualPower;
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 72;				// 72
							aDataSet.data = channel_data[i].startupTime;
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 73;				// 73
							aDataSet.data = channel_data[i].minimumPower;
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 74;				// 74
							aDataSet.data = channel_data[i].automaticMode;
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 75;				// 75
							aDataSet.data = channel_data[i].stopEnable;
							serialport_writeCarriage(&aDataSet);
							aDataSet.id = 76;				// 76
							aDataSet.data = channel_data[i].threshold;
							serialport_writeCarriage(&aDataSet);							
						}
						//aDataSet.id = 77;					// 77
						//aDataSet.index = 1;
						//aDataSet.data = alphaDisplay.backlight;
						//serialport_writeCarriage(&aDataSet);
						//aDataSet.index = 2;
						//aDataSet.data = alphaDisplay.contrast;
						//serialport_writeCarriage(&aDataSet);						
						aDataSet.id = 78;					// 78
						aDataSet.index = 1;
						aDataSet.data = led_data.mode;
						serialport_writeCarriage(&aDataSet);
						aDataSet.id = 79;					// 79
						for (i=0;i<3;i++)
						{
							aDataSet.index = i+1;
							aDataSet.data = led_data.manualPower[i];
							serialport_writeCarriage(&aDataSet);
						}
						//aDataSet.id = 80;					// 80
						//for (i=0;i<255;i++)				
						//{
							//aDataSet.index = i+1;
							//aDataSet.data = alphaDisplay.content[i];
							//serialport_writeCarriage(&aDataSet);
						//}
						//aDataSet.id = 81;					// 81
						//for (i=0;i<31;i++)
						//{
							//aDataSet.index = i+1;
							//aDataSet.data = alphaDisplay.screen[i];
							//serialport_writeCarriage(&aDataSet);
						//}									
						break;
					
					case 02:
						if (aDataSet.index == 0)		// ask for all of them
						{
							aDataSet.index = 1;
							aDataSet.data = FIRMWAREVERSION;
							serialport_writeCarriage(&aDataSet);
							aDataSet.index = 2;
							aDataSet.data = EEPROMVERSION;
							serialport_writeCarriage(&aDataSet);
						}
						else if (aDataSet.index == 1)
						{
							aDataSet.data = FIRMWAREVERSION;
							serialport_writeCarriage(&aDataSet);
						}
						else if (aDataSet.index == 2)
						{
							aDataSet.data = EEPROMVERSION;
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 11:
						if (aDataSet.index == 0)		// ask for all of them
						{							
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[0].minTemp[i];
								serialport_writeCarriage(&aDataSet);	
							}							
						} 
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[0].minTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}					
						break;
						
					case 21:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[0].maxTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[0].maxTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 12:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[1].minTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[1].minTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 22:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[1].maxTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[1].maxTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 13:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[2].minTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[2].minTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 23:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[2].maxTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[2].maxTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 14:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[3].minTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[3].minTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 24:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<24;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[3].maxTemp[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[3].maxTemp[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 31:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<8;i++)
							{
								aDataSet.index = i+17;
								aDataSet.data = spare_temperature[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = spare_temperature[aDataSet.index-17];
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 32:
						aDataSet.index = 1;
						aDataSet.data = tempSensor_getOneWireAmount();
						serialport_writeCarriage(&aDataSet);
						break;
					
					case 33:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<(8*tempSensor_getOneWireAmount());i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = tempSensor_getOneWireID(i);
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = tempSensor_getOneWireID(aDataSet.index-1);
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 51:
						switch (aDataSet.index)
						{
							case 0:
								aDataSet.index = 1;
								aDataSet.data = alert_data.overtempEnable;
								serialport_writeCarriage(&aDataSet);
								aDataSet.index = 2;
								aDataSet.data = alert_data.fanblockEnable;
								serialport_writeCarriage(&aDataSet);
								break;
								
							case 1:
								aDataSet.data = alert_data.overtempEnable;
								serialport_writeCarriage(&aDataSet);
								break;
								
							case 2:
								aDataSet.data = alert_data.fanblockEnable;
								serialport_writeCarriage(&aDataSet);
								break;			
						}
						break;
					
					case 70:
						switch (aDataSet.index)
						{
							case 0:
								aDataSet.index = 1;
								aDataSet.data = pulsePerLiter;
								serialport_writeCarriage(&aDataSet);
								aDataSet.index = 2;
								aDataSet.data = alert_data.minWaterFlow;
								serialport_writeCarriage(&aDataSet);
								break;
							
							case 1:
								aDataSet.data = pulsePerLiter;
								serialport_writeCarriage(&aDataSet);
								break;
							
							case 2:
								aDataSet.data = alert_data.minWaterFlow;
								serialport_writeCarriage(&aDataSet);
								break;
						}
						break;
					
					case 71:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].manualPower;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].manualPower;
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 72:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].startupTime;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].startupTime;
							serialport_writeCarriage(&aDataSet);
						}
						break;
					
					case 73:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].minimumPower;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].minimumPower;
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 74:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].automaticMode;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].automaticMode;
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 75:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].stopEnable;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].stopEnable;
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 76:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<4;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = channel_data[i].threshold;
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = channel_data[aDataSet.index-1].threshold;
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 77:							// display backlight and contrast
						//switch (aDataSet.index)
						//{
							//case 0:
								//aDataSet.index = 1;
								//aDataSet.data = alphaDisplay.backlight;
								//serialport_writeCarriage(&aDataSet);
								//aDataSet.index = 2;
								//aDataSet.data = alphaDisplay.contrast;
								//serialport_writeCarriage(&aDataSet);
								//break;
						//
							//case 1:
								//aDataSet.data = alphaDisplay.backlight;
								//serialport_writeCarriage(&aDataSet);
								//break;
						//
							//case 2:
								//aDataSet.data = alphaDisplay.contrast;
								//serialport_writeCarriage(&aDataSet);
								//break;
						//}
						break;
						
					case 78:
						aDataSet.index = 1;
						aDataSet.data = led_data.mode;
						serialport_writeCarriage(&aDataSet);
						break;
						
					case 79:
						if (aDataSet.index == 0)		// ask for all of them
						{
							for (i=0;i<3;i++)
							{
								aDataSet.index = i+1;
								aDataSet.data = led_data.manualPower[i];
								serialport_writeCarriage(&aDataSet);
							}
						}
						else							// ask for a specific one
						{
							aDataSet.data = led_data.manualPower[aDataSet.index-1];
							serialport_writeCarriage(&aDataSet);
						}
						break;
						
					case 80:						// display content
						//if (aDataSet.index == 0)		// ask for all of them
						//{
							//for (i=0;i<255;i++)
							//{
								//aDataSet.index = i+1;
								//aDataSet.data = alphaDisplay.content[i];
								//serialport_writeCarriage(&aDataSet);
							//}
						//}
						//else							// ask for a specific one
						//{
							//aDataSet.data = alphaDisplay.content[aDataSet.index-1];
							//serialport_writeCarriage(&aDataSet);
						//}
						break;
						
					case 81:						// display screens
						//if (aDataSet.index == 0)		// ask for all of them
						//{
							//for (i=0;i<31;i++)
							//{
								//aDataSet.index = i+1;
								//aDataSet.data = alphaDisplay.screen[i];
								//serialport_writeCarriage(&aDataSet);
							//}
						//}
						//else							// ask for a specific one
						//{
							//aDataSet.data = alphaDisplay.screen[aDataSet.index-1];
							//serialport_writeCarriage(&aDataSet);
						//}
						break;
					
				}				
			}
		
									
		}	
		
    }		// while(1) end
}			// main end
/// <summary>
/// Get one line of text from the program memory and put it into the buffer
/// </summary>
void SerialMenu::getLine(uint8_t stringIndex)
{
    strcpy_P(_buffer, (char*)pgm_read_word(&(ConfigMenu_string_table[stringIndex])));
}
Example #3
0
////////////////////////////////////////////////////////////////////////////////////////////////////
//Parse HTML message transferred by parameter, buf. It returns 1 when it encounters to the EOF of HTML file, ohterwise 0
uint8_t HTMLParser::Parsing(char * buf)
{
	uint8_t i, retval, index = 0;
	char msgbuf[10];
	char *tmpbuf, *tmpbuf2;


	if(bInParsing == NO_PARSING)
	{

		memset(parserBuf, 0, PARSEBUF_SIZE); 
		parserBufIndex = 0;
	}
		
	while(buf[index] != '\0')
	{
		if(buf[index] == 0x0a)
		{
			if(parserBuf[parserBufIndex - 1] == 0x0d)
			{
				if(parserBufIndex > 1)
				{					
					/////////////////////////
					// Do Parsing a sentence terminated by CR and LF
					Serial.println((char *)parserBuf);

					tmpbuf = strtok((char *)parserBuf, " ");

					Serial.println((char *)tmpbuf);
					
					memset(msgbuf, 0, 10);
				       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[0]))); // Necessary casts and dereferencing, just copy. 
				//	Serial.println((char *)msgbuf);
					
					if(!strcmp((const char*)tmpbuf, (const char*)msgbuf)) 	// GET
					{
						tmpbuf = strtok(NULL, " ");
						memset(msgbuf, 0, 10);
						Serial.println((char *)tmpbuf);
						
				       	strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[1]))); // Necessary casts and dereferencing, just copy. 
						if(strstr((char const*)tmpbuf, (const char *)msgbuf) != NULL)
						{
							if((tmpbuf2 = strchr((char const*)tmpbuf, '=')) != NULL)
							{
								memset(msgbuf, 0, 10);
				       			strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[2]))); // Necessary casts and dereferencing, just copy. 
								if(strstr((char const*)tmpbuf2, (const char *)msgbuf) != NULL){
									Serial.println((char *)msgbuf);
									SetParam(FW_CMD);
								}
								
								memset(msgbuf, 0, 10);
				       			strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[3]))); // Necessary casts and dereferencing, just copy. 
								if(strstr((char const*)tmpbuf2, (const char *)msgbuf) != NULL){
									SetParam(BW_CMD);
									Serial.println((char *)msgbuf);
								}

								memset(msgbuf, 0, 10);
				       			strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[4]))); // Necessary casts and dereferencing, just copy. 
								if(strstr((char const*)tmpbuf2, (const char *)msgbuf) != NULL){
									Serial.println((char *)msgbuf);
									SetParam(RT_CMD);
								}
								

								memset(msgbuf, 0, 10);
				       			strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[5]))); // Necessary casts and dereferencing, just copy. 
								if(strstr((char const*)tmpbuf2, (const char *)msgbuf) != NULL){
									SetParam(LF_CMD);
									Serial.println((char *)msgbuf);
								}
							}
								
						}

						tmpbuf = strtok(NULL, " ");
						Serial.println((char *)tmpbuf);
					}
					memset(parserBuf, 0, PARSEBUF_SIZE);
					parserBufIndex = 0;
				}else
				{
					bInParsing = NO_PARSING;
					return 1; // Parsing was finished.
				}
			}
			index++;
		}else 
		{			
			parserBuf[parserBufIndex++] = buf[index++];
		}
	}

	if(parserBufIndex > 0)
		bInParsing = IN_PARSING;
	
	return 0;
}
Example #4
0
char* monthStr(uint8_t month)
{
    strcpy_P(buffer, (PGM_P)pgm_read_word(&(monthNames_P[month])));
	return buffer;
}
Example #5
0
/***************************************************************************** 
 * Accessors - get various data from an object given the index
 * _get_format() 	- return format string for an index
 */
char *_get_format(const index_t i, char *format)
{
	strncpy_P(format, (PGM_P)pgm_read_word(&cfgArray[i].format), CMD_FORMAT_LEN);
	return (format);
}
Example #6
0
/*-----------------------------------------------------------------------------
*  Ausgangszustand lesen
*/
BOOL DigOutState(TDigOutNumber number) {

   TFuncState fState = (TFuncState)pgm_read_word(&sDigOutFuncs[number].fState);
   return fState();
}
Example #7
0
void __act_setSpeed(__ACTUATOR* act, DRIVE_SPEED speed){
	// clamp it to the given range
	speed = CLAMP(speed, DRIVE_SPEED_MIN, DRIVE_SPEED_MAX);

	// Get the driver class
	const __ACTUATOR_DRIVER_CLASS* driver=act->class;

	// Call the setSpeed method on the class
	if(driver){
		void (*fn)(__ACTUATOR*,DRIVE_SPEED speed) = (void (*)(__ACTUATOR*, DRIVE_SPEED speed))pgm_read_word(&driver->setSpeed);
		if(fn!=null){
			fn(act,(act->inverted) ? speed*-1 : speed);
		}
	}

	// Store the new speed - do this at the end so that the setSpeed method
	// can access the previous speed
	act->required_speed = speed;
}
Example #8
0
//--------------------------------------------------------------------
//[LEG INVERSE KINEMATICS] Calculates the angles of the coxa, femur and tibia for the given position of the feet
//IKFeetPosX            - Input position of the Feet X
//IKFeetPosY            - Input position of the Feet Y
//IKFeetPosZ            - Input Position of the Feet Z
//IKSolution            - Output TRUE if the solution is possible
//IKSolutionWarning     - Output TRUE if the solution is NEARLY possible
//IKSolutionError    - Output TRUE if the solution is NOT possible
//mFemurAngles           - Output Angle of Femur in degrees
//mTibiaAngles           - Output Angle of Tibia in degrees
//mCoxaAngles            - Output Angle of Coxa in degrees
//--------------------------------------------------------------------
u8 PhoenixCore::getLegIK(u8 leg, s16 IKFeetPosX, s16 IKFeetPosY, s16 IKFeetPosZ)
{
    u32    IKSW2;            //Length between Shoulder and Wrist, decimals = 2
    u32    IKA14;            //Angle of the line S>W with respect to the ground in radians, decimals = 4
    u32    IKA24;            //Angle of the line S>W with respect to the femur in radians, decimals = 4
    s16            IKFeetPosXZ;    //Diagonal direction from Input X and Z
#if (CONFIG_DOF_PER_LEG == 4)
    // these were shorts...
    long            TarsOffsetXZ;    //Vector value \ ;
    long            TarsOffsetY;     //Vector value / The 2 DOF IK calcs (femur and tibia) are based upon these vectors
    long            TarsToGroundAngle1;    //Angle between tars and ground. Note: the angle are 0 when the tars are perpendicular to the ground
    long            TGA_A_H4;
    long            TGA_B_H3;
#else
    #define TarsOffsetXZ 0	    // Vector value
    #define TarsOffsetY  0	    //Vector value / The 2 DOF IK calcs (femur and tibia) are based upon these vectors
#endif

    long            Temp1;
    long            Temp2;
    long            T3;
    long            hyp2XY;
    u8              ret;
#if (CONFIG_DOF_PER_LEG == 4)
    s16             sin4;
    s16             cos4;
#endif

    //Calculate IKCoxaAngle and IKFeetPosXZ
    s16 atan4 = arctan2 (IKFeetPosX, IKFeetPosZ, &hyp2XY);
    mCoxaAngles[leg] = (((long)atan4*180) / 3141) + (s16)pgm_read_word(&TBL_COXA_ANGLE[leg]);

    //Length between the Coxa and tars [foot]
    IKFeetPosXZ = hyp2XY / DEC_EXP_2;

#if (CONFIG_DOF_PER_LEG == 4)
    // Some legs may have the 4th DOF and some may not, so handle this here...
    //Calc the TarsToGroundAngle1:
    if ((u8)pgm_read_byte(&TBL_TARS_LENGTH[leg])) {    // We allow mix of 3 and 4 DOF legs...
        TarsToGroundAngle1 = -cTarsConst + cTarsMulti*IKFeetPosY + ((long)(IKFeetPosXZ*cTarsFactorA))/DEC_EXP_1 - ((long)(IKFeetPosXZ*IKFeetPosY)/(cTarsFactorB));
        if (IKFeetPosY < 0)     //Always compensate TarsToGroundAngle1 when IKFeetPosY it goes below zero
            TarsToGroundAngle1 = TarsToGroundAngle1 - ((long)(IKFeetPosY*cTarsFactorC)/DEC_EXP_1);     //TGA base, overall rule
        if (TarsToGroundAngle1 > 400)
            TGA_B_H3 = 200 + (TarsToGroundAngle1/2);
        else
            TGA_B_H3 = TarsToGroundAngle1;

        if (TarsToGroundAngle1 > 300)
            TGA_A_H4 = 240 + (TarsToGroundAngle1/5);
        else
            TGA_A_H4 = TarsToGroundAngle1;

        if (IKFeetPosY > 0)    //Only compensate the TarsToGroundAngle1 when it exceed 30 deg (A, H4 PEP note)
            TarsToGroundAngle1 = TGA_A_H4;
        else if (((IKFeetPosY <= 0) & (IKFeetPosY > -10))) // linear transition between case H3 and H4 (from PEP: H4-K5*(H3-H4))
            TarsToGroundAngle1 = (TGA_A_H4 -(((long)IKFeetPosY*(TGA_B_H3-TGA_A_H4))/DEC_EXP_1));
        else                //IKFeetPosY <= -10, Only compensate TGA1 when it exceed 40 deg
            TarsToGroundAngle1 = TGA_B_H3;

        //Calc Tars Offsets:
        sincos(TarsToGroundAngle1, &sin4, &cos4);
        TarsOffsetXZ = ((long)sin4*(u8)pgm_read_byte(&TBL_TARS_LENGTH[leg]))/DEC_EXP_4;
        TarsOffsetY = ((long)cos4*(u8)pgm_read_byte(&TBL_TARS_LENGTH[leg]))/DEC_EXP_4;
    } else {
        TarsOffsetXZ = 0;
        TarsOffsetY = 0;
    }
#endif

    //Using GetAtan2 for solving IKA1 and IKSW
    //IKA14 - Angle between SW line and the ground in radians
    IKA14 = arctan2(IKFeetPosY-TarsOffsetY, IKFeetPosXZ-(u8)pgm_read_byte(&TBL_COXA_LENGTH[leg])-TarsOffsetXZ, &hyp2XY);

    //IKSW2 - Length between femur axis and tars
    IKSW2 = hyp2XY;

    //IKA2 - Angle of the line S>W with respect to the femur in radians
    Temp1 = (( ((long)(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])*(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])) -
                ((long)(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg])*(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg])) )*DEC_EXP_4 + ((long)IKSW2*IKSW2));
    Temp2 = (long)(2*(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg]))*DEC_EXP_2 * (u32)IKSW2;
    T3 = Temp1 / (Temp2/DEC_EXP_4);
    IKA24 = arccos (T3 );

    //IKFemurAngle
    if (mBoolUpsideDown)
        mFemurAngles[leg] = (long)(IKA14 + IKA24) * 180 / 3141 - 900 + OFFSET_FEMUR_HORN(leg);//Inverted, up side down
    else
        mFemurAngles[leg] = -(long)(IKA14 + IKA24) * 180 / 3141 + 900 + OFFSET_FEMUR_HORN(leg);//Normal

    //IKTibiaAngle
    Temp1 = ((((long)(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])*(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])) +
            ((long)(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg])*(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg])))*DEC_EXP_4 - ((long)IKSW2*IKSW2));
    Temp2 = (2*(u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])*(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg]));
    long angleRad4 = arccos(Temp1 / Temp2);

#ifdef OPT_WALK_UPSIDE_DOWN
    if (mBoolUpsideDown)
        mTibiaAngles[leg] = (1800-(long)angleRad4*180/3141);//Full range tibia, wrong side (up side down)
    else
        mTibiaAngles[leg] = -(1800-(long)angleRad4*180/3141);//Full range tibia, right side (up side up)
#else
#ifdef PHANTOMX_V2     // BugBug:: cleaner way?
    mTibiaAngles[leg] = -(1450-(long)angleRad4*180/3141); //!!!!!!!!!!!!145 instead of 1800
#else
    mTibiaAngles[leg] = -(900-(long)angleRad4*180/3141);
#endif
#endif

#if (CONFIG_DOF_PER_LEG == 4)
    //Tars angle
    if ((u8)pgm_read_byte(&TBL_TARS_LENGTH[leg])) {    // We allow mix of 3 and 4 DOF legs...
        mTarsAngles[leg] = (TarsToGroundAngle1 + mFemurAngles[leg] - mTibiaAngles[leg]) +
                           OFFSET_TARS_HORN(leg);
    }
#endif

    //Set the Solution quality
    if(IKSW2 < ((word)((u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])+(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg])-30)*DEC_EXP_2))
        ret = STATUS_OK;
    else {
        if(IKSW2 < ((word)((u8)pgm_read_byte(&TBL_FEMUR_LENGTH[leg])+(u8)pgm_read_byte(&TBL_TIBIA_LENGTH[leg]))*DEC_EXP_2))
            ret = STATUS_WARNING;
        else
            ret = STATUS_ERROR;
    }

  return ret;
}
Example #9
0
File: menu.cpp Project: lsitec/PCR
void enterPassword(int delta_x, int delta_y)
{
    char pw_display_str[PW_SIZE] = "";
    char number[PW_SIZE] = "";

    if (delta_y < MNEG)
    {
        if(pw_index!=PW_SIZE)
        {
            if (pw_display[pw_index]!=0)
                pw_display[pw_index] = pw_display[pw_index] - 1;
            else
                pw_display[pw_index] = 9;
        }
        else
        {
            check_pw = true;
        }
    }
    else if (delta_y > MPOS)
    {
        if(pw_index!=PW_SIZE)
        {
            if (pw_display[pw_index]!=9)
                pw_display[pw_index] = pw_display[pw_index] + 1;
            else
                pw_display[pw_index] = 0;
        }
        else
        {
            check_pw = true;
        }
    }
    else if (delta_x < MNEG)
    {
        if (pw_index!=0)
            pw_index--;
        else
            pw_index = PW_SIZE;
    }
    else if (delta_x > MPOS)
    {
        if (pw_index!=PW_SIZE)
            pw_index++;
        else
            pw_index = 0;
    }

    for(int i = 0; i<PW_SIZE; i++)
    {
        itoa(pw_display[i], number, 10);
        if(i)
            strcat(pw_display_str, number);
        else
            strcpy(pw_display_str, number);
    }

    strcpy(pw_guess, pw_display_str);
    if (check_pw)
    {
        lock_status = password.is(pw_guess);
        if (lock_status)
        {
            miConfig.sibling = &miConfLock;
            for(int i=0;i<PW_SIZE;i++) { pw_display[i] = 0; }
            menu.start();
            return;
        }
        else
        {
            miConfig.sibling = &miConfUnlock;
        }
        check_pw = false;
    }

    if (lock_status)
        strcpy_P(screen.title, strConfLock);
    else
        strcpy_P(screen.title, strConfUnlock);

    strcpy_P(screen.content[0], strNull);
    strcat_P(pw_display_str, space);
    strcat_P(pw_display_str, ok);
    strcpy(screen.content[1], pw_display_str);
    strcpy_P(screen.content[2], (char*)pgm_read_word(&(indicators[pw_index])));
}
Example #10
0
u8 PhoenixCore::loop(void)
{
    bool            allDown;
    long            lBodyX;         //Output Position X of feet with Rotation
    long            lBodyY;         //Output Position Y of feet with Rotation
    long            lBodyZ;         //Output Position Z of feet with Rotation
    u8              ret = STATUS_OK;

    //Start time
    mTimerStart = millis();

    if (mCommitTime != 0) {
        if (mTimerStart >= mCommitTime) {
            mServo->commit(mCurServoMoveTime);
            mCommitTime = 0;
            mTimerStart = millis();
        } else {
            return ret;
        }
    }

    // every 500ms
    if (mTimerStart - mTimerLastCheck > 500) {
        mCurVolt = mServo->getBattVolt();
        mTimerLastCheck = mTimerStart;

        if (mCurVolt < CONFIG_VOLT_OFF) {
            mVoltWarnBeepCnt++;
            if (mVoltWarnBeepCnt > 10) {

                return STATUS_BATT_FAIL;
            }
            else
                ret |= STATUS_BATT_WARN;
        } else {
            mVoltWarnBeepCnt = 0;
        }
    }

    if (mBoolUpsideDown) {
        mPtrCtrlState->c3dTravelLen.x = -mPtrCtrlState->c3dTravelLen.x;
        mPtrCtrlState->c3dBodyPos.x = -mPtrCtrlState->c3dBodyPos.x;
        mPtrCtrlState->c3dSingleLeg.x = -mPtrCtrlState->c3dSingleLeg.x;
        mPtrCtrlState->c3dBodyRot.z = -mPtrCtrlState->c3dBodyRot.z;
    }

    //Single leg control
    allDown = ctrlSingleLeg();

    //doGait
    doGaitSeq();

    //Balance calculations
    mTotalTransX = 0;     //reset values used for calculation of balance
    mTotalTransZ = 0;
    mTotalTransY = 0;
    mTotalXBal1  = 0;
    mTotalYBal1  = 0;
    mTotalZBal1  = 0;

    if (mPtrCtrlState->fBalanceMode) {
        for (u8 i = 0; i < CONFIG_NUM_LEGS / 2; i++) {    // balance calculations for all Right legs
            calcBalOneLeg(i, -mLegPosXs[i]+mGaitPosXs[i],
                          mLegPosZs[i]+mGaitPosZs[i],
                          (mLegPosYs[i]-(s16)pgm_read_word(&TBL_INT_POS_Y[i]))+mGaitPosYs[i]);
        }

        for (u8 i = CONFIG_NUM_LEGS / 2; i < CONFIG_NUM_LEGS; i++) {    // balance calculations for all Right legs
            calcBalOneLeg(i, mLegPosXs[i]+mGaitPosXs[i],
                          mLegPosZs[i]+mGaitPosZs[i],
                          (mLegPosYs[i]-(s16)pgm_read_word(&TBL_INT_POS_Y[i]))+mGaitPosYs[i]);
        }
        balanceBody();
    }

    //Do IK for all Right legs
    for (u8 i = 0; i < CONFIG_NUM_LEGS / 2; i++) {
        getBodyIK(i,
                  -mLegPosXs[i]+mPtrCtrlState->c3dBodyPos.x+mGaitPosXs[i] - mTotalTransX,
                  mLegPosZs[i]+mPtrCtrlState->c3dBodyPos.z+mGaitPosZs[i] - mTotalTransZ,
                  mLegPosYs[i]+mPtrCtrlState->c3dBodyPos.y+mGaitPosYs[i] - mTotalTransY,
                  mGaitRotYs[i],
                  &lBodyX, &lBodyY, &lBodyZ);

        ret |= getLegIK(i, mLegPosXs[i]-mPtrCtrlState->c3dBodyPos.x+lBodyX-(mGaitPosXs[i] - mTotalTransX),
                        mLegPosYs[i]+mPtrCtrlState->c3dBodyPos.y-lBodyY+mGaitPosYs[i] - mTotalTransY,
                        mLegPosZs[i]+mPtrCtrlState->c3dBodyPos.z-lBodyZ+mGaitPosZs[i] - mTotalTransZ);
    }

    //Do IK for all Left legs
    for (u8 i = CONFIG_NUM_LEGS / 2; i < CONFIG_NUM_LEGS; i++) {
        getBodyIK(i,
                  mLegPosXs[i]-mPtrCtrlState->c3dBodyPos.x+mGaitPosXs[i] - mTotalTransX,
                  mLegPosZs[i]+mPtrCtrlState->c3dBodyPos.z+mGaitPosZs[i] - mTotalTransZ,
                  mLegPosYs[i]+mPtrCtrlState->c3dBodyPos.y+mGaitPosYs[i] - mTotalTransY,
                  mGaitRotYs[i],
                  &lBodyX, &lBodyY, &lBodyZ);

        ret |= getLegIK(i, mLegPosXs[i]+mPtrCtrlState->c3dBodyPos.x-lBodyX+mGaitPosXs[i] - mTotalTransX,
                       mLegPosYs[i]+mPtrCtrlState->c3dBodyPos.y-lBodyY+mGaitPosYs[i] - mTotalTransY,
                       mLegPosZs[i]+mPtrCtrlState->c3dBodyPos.z-lBodyZ+mGaitPosZs[i] - mTotalTransZ);
    }

    if (mBoolUpsideDown) { //Need to set them back for not messing with the smoothControl
        mPtrCtrlState->c3dBodyPos.x = -mPtrCtrlState->c3dBodyPos.x;
        mPtrCtrlState->c3dSingleLeg.x = -mPtrCtrlState->c3dSingleLeg.x;
        mPtrCtrlState->c3dBodyRot.z = -mPtrCtrlState->c3dBodyRot.z;
    }

    //Check mechanical limits
    validateAngles();

    //Drive Servos
    if (mPtrCtrlState->fHexOn) {
        //Calculate Servo Move time
        if ((abs(mPtrCtrlState->c3dTravelLen.x) > CONFIG_TRAVEL_DEAD_ZONE) ||
            (abs(mPtrCtrlState->c3dTravelLen.z) > CONFIG_TRAVEL_DEAD_ZONE) ||
            (abs(mPtrCtrlState->c3dTravelLen.y * 2) > CONFIG_TRAVEL_DEAD_ZONE)) {
            mCurServoMoveTime = mNormGaitSpeed + (mPtrCtrlState->bInputTimeDelay * 2) + mPtrCtrlState->wSpeedControl;
            //Add aditional delay when Balance mode is on
            if (mPtrCtrlState->fBalanceMode)
                mCurServoMoveTime = mCurServoMoveTime + 100;
        } else { //Movement speed excl. Walking
            mCurServoMoveTime = 200 + mPtrCtrlState->wSpeedControl;
        }

        // note we broke up the servo driver into start/commit that way we can output all of the servo information
        // before we wait and only have the termination information to output after the wait.  That way we hopefully
        // be more accurate with our timings...
        updateServos();

        // See if we need to sync our processor with the servo driver while walking to ensure the prev is completed
        // before sending the next one
        // Finding any incident of GaitPos/Rot <>0:
        for (u8 i = 0; i < CONFIG_NUM_LEGS; i++) {
            if ( (mGaitPosXs[i] > GP_DIFF_LIMIT) || (mGaitPosXs[i] < -GP_DIFF_LIMIT) ||
                 (mGaitPosZs[i] > GP_DIFF_LIMIT) || (mGaitPosZs[i] < -GP_DIFF_LIMIT) ||
                 (mGaitRotYs[i] > GP_DIFF_LIMIT) || (mGaitRotYs[i] < -GP_DIFF_LIMIT)) {
                mExtraCycle = mNrLiftedPos + 1;//For making sure that we are using timed move until all legs are down
                break;
            }
        }

        //printf(F("ExtraCycle:%d\n"), mExtraCycle);
        if (mExtraCycle > 0) {
            mExtraCycle--;
            mBoolWalking = (mExtraCycle != 0);
            mCommitTime  = mTimerStart + mOldServoMoveTime + CONFIG_SERVO_MARGIN;
            //printf(F("Next1:%ld\n"), mCommitTime);

            if (mBoolDbgOutput) {
                printf(F("BRX:%d, Walk:%d, GS:%d\n"), mPtrCtrlState->c3dBodyRot.x, mBoolWalking, mGaitStep);
                printf(F("LEFT  GPX:%5d, GPY:%5d, GPZ:%5d\n"), mGaitPosXs[IDX_LF], mGaitPosYs[IDX_LF], mGaitPosZs[IDX_LF]);
                printf(F("RIGHT GPX:%5d, GPY:%5d, GPZ:%5d\n"), mGaitPosXs[IDX_RF], mGaitPosYs[IDX_RF], mGaitPosZs[IDX_RF]);
            }
        } else {
            // commit immediately
            mCommitTime = mTimerStart + mOldServoMoveTime + CONFIG_SERVO_MARGIN;
            //printf(F("Next2:%ld\n"), mCommitTime);
        }

        if (mBoolDbgOutput) {
            printf(F("TY:%5d, LFZ:%5d\n"), mTotalYBal1, mLegPosZs[IDX_LF]);
        }


    } else {
        //Turn the bot off - May need to add ajust here...
        if (mPtrCtrlState->fHexOnOld) {
            printf(F("RESET LEGS !!!\n"));
            mCurServoMoveTime = 600;
            updateServos();
            mServo->commit(mCurServoMoveTime);
            delay(600);
        } else {
            mServo->release();
        }
        // We also have a simple debug monitor that allows us to
        // check things. call it here..
#ifdef CONFIG_TERMINAL
        if (showTerminal())
            return ret;
#endif
    }
    mOldServoMoveTime = mCurServoMoveTime;

    return ret;
}
Example #11
0
bool PhoenixCore::ctrlSingleLeg(void)
{
    bool allDown = TRUE;

    for (u8 i = 0; i < CONFIG_NUM_LEGS; i++) {
        if (mLegPosYs[i] != (s16)pgm_read_word(&TBL_INT_POS_Y[i])) {
            allDown = FALSE;
            break;
        }
    }

    if (mPtrCtrlState->bSingleLegCurSel < CONFIG_NUM_LEGS) {
        if (mPtrCtrlState->bSingleLegCurSel != mPtrCtrlState->bSingleLegOldSel) {
            if (allDown) { //Lift leg a bit when it got selected
                mLegPosYs[mPtrCtrlState->bSingleLegCurSel] = (s16)pgm_read_word(&TBL_INT_POS_Y[mPtrCtrlState->bSingleLegCurSel]) - 20;
                //Store current status
                mPtrCtrlState->bSingleLegOldSel = mPtrCtrlState->bSingleLegCurSel;
            } else {//Return prev leg back to the init position
                mLegPosXs[mPtrCtrlState->bSingleLegOldSel] = (s16)pgm_read_word(&TBL_INT_POS_X[mPtrCtrlState->bSingleLegOldSel]);
                mLegPosYs[mPtrCtrlState->bSingleLegOldSel] = (s16)pgm_read_word(&TBL_INT_POS_Y[mPtrCtrlState->bSingleLegOldSel]);
                mLegPosZs[mPtrCtrlState->bSingleLegOldSel] = (s16)pgm_read_word(&TBL_INT_POS_Z[mPtrCtrlState->bSingleLegOldSel]);
            }
        }
        else if (!mPtrCtrlState->fSingleLegHold) {
            //mLegPosYs[mPtrCtrlState->bSingleLegCurSel] = mLegPosYs[mPtrCtrlState->bSingleLegCurSel]+mPtrCtrlState->c3dSingleLeg.y;
            mLegPosYs[mPtrCtrlState->bSingleLegCurSel] = (s16)pgm_read_word(&TBL_INT_POS_Y[mPtrCtrlState->bSingleLegCurSel])+mPtrCtrlState->c3dSingleLeg.y;// Using DIY remote Zenta prefer it this way
            mLegPosXs[mPtrCtrlState->bSingleLegCurSel] = (s16)pgm_read_word(&TBL_INT_POS_X[mPtrCtrlState->bSingleLegCurSel])+mPtrCtrlState->c3dSingleLeg.x;
            mLegPosZs[mPtrCtrlState->bSingleLegCurSel] = (s16)pgm_read_word(&TBL_INT_POS_Z[mPtrCtrlState->bSingleLegCurSel])+mPtrCtrlState->c3dSingleLeg.z;
        }
    } else {//All legs to init position
        if (!allDown) {
            for(u8 i = 0; i < CONFIG_NUM_LEGS; i++) {
                mLegPosXs[i] = (s16)pgm_read_word(&TBL_INT_POS_X[i]);
                mLegPosYs[i] = (s16)pgm_read_word(&TBL_INT_POS_Y[i]);
                mLegPosZs[i] = (s16)pgm_read_word(&TBL_INT_POS_Z[i]);
            }
        }
        if (mPtrCtrlState->bSingleLegOldSel != 255)
            mPtrCtrlState->bSingleLegOldSel = 255;
    }
    return allDown;
}
Example #12
0
const char* pin_def_t::get_name_P(void) const
{
  return reinterpret_cast<const char*>(pgm_read_word(&name));
}
Example #13
0
bool pin_def_t::is_valid_P(void) const
{
  return pgm_read_word(&name) != 0;
}
Example #14
0
void m_ctcss_submenu(char key)
{
	char print = 1;
	uint8_t ctcss_index;
	uint8_t	ctcss_index_other;
	
	m_reset_timer();

	if(m_state == CTCSS_SEL_TX)
	{
		ctcss_index = config.ctcssIndexTx;
		ctcss_index_other = config.ctcssIndexRx;
	}	
	else
	{
		ctcss_index = config.ctcssIndexRx;
		ctcss_index_other = config.ctcssIndexTx;
	}	


	// avoid "same as RX" / "same as TX" for bith settings
	// if it happens (eg invalid config), force current index to "CTCSS off" position
	if(!ctcss_index && (ctcss_index == ctcss_index_other)){
		ctcss_index = 1;
	}

	if (key != -1)
	{
		switch(key)
		{
			case KC_D1:
			{
				ctcss_index = ctcss_index < CTCSS_TABMAX-1 ? ctcss_index+1 : 0;
				// "same as RX" / "same as TX" can only be selected for TX or RX
				// otherwise there will be a paradoxon and the whole universe will cease to exist ;)
				if(!ctcss_index && (ctcss_index == ctcss_index_other)){
					ctcss_index++;
				}
				break;
			}
			case KC_D2:
			{
				ctcss_index = ctcss_index ? ctcss_index-1 : CTCSS_TABMAX-1;
				// "same as RX" / "same as TX" can only be selected for TX or RX
				// otherwise there will be a paradoxon and the whole universe will cease to exist ;)
				if(!ctcss_index && (ctcss_index == ctcss_index_other)){
					ctcss_index=CTCSS_TABMAX-1;
				}
				break;
			}
			case KC_ENTER:
			{
				print = 0;

				if(m_state == CTCSS_SEL_TX)
				{
					uint16_t freq;

					if(ctcss_index){
						freq = pgm_read_word(&ctcss_tab[ctcss_index]);
					}
					else{
						freq = pgm_read_word(&ctcss_tab[ctcss_index_other]);
					}						
						
					if(freq)
					{						
						tone_start_pl(freq);
					}
					else
					{
						tone_stop_pl();
						tone_decoder_stop();
						lcd_cpos(0);
						printf_P(PSTR("TX CTCSS"));
						lcd_fill();
						lcd_cpos(0);
						vTaskDelay(100);
						printf_P(PSTR("OFF"));
						lcd_fill();
						vTaskDelay(100);
					}
				}
				else
				{
					// CTCSS_SEL_RX
					uint16_t freq;

					if(ctcss_index){
						freq = pgm_read_word(&ctcss_tab[ctcss_index]);
					}
					else{
						freq = pgm_read_word(&ctcss_tab[ctcss_index_other]);
					}
									
					if(freq)
					{
						tone_decoder_start_freq(freq);
					}
					else
					{
						tone_decoder_stop();
						lcd_cpos(0);
						printf_P(PSTR("RX CTCSS"));
						lcd_fill();
						lcd_cpos(0);
						vTaskDelay(100);
						printf_P(PSTR("OFF"));
						lcd_fill();
						vTaskDelay(100);
					}
				}

				lcd_cpos(0);
				printf_P(m_ok_str);
				lcd_fill();
				m_timer=0;
				break;
			}
			case 0:
			{
				tone_stop_pl();
				tone_decoder_stop();
				lcd_cpos(0);
				printf_P(PSTR("TONE OFF"));
				lcd_fill();
				vTaskDelay(200);
			}
			// no break
			case KC_EXIT:
			{
				print = 0;
				m_timer = 0;
				break;
			}
		}
	}

	if(m_state == CTCSS_SEL_TX)
	{
		config.ctcssIndexTx = ctcss_index;
	}	
	else
	{
		config.ctcssIndexRx = ctcss_index;
	}	
	
	if(print)
	{
		uint16_t freq;
		char c[6];

		memset(c,0,sizeof c);
		
		if(ctcss_index){
			freq = pgm_read_word(&ctcss_tab[ctcss_index]);
		}
		else{
			freq = pgm_read_word(&ctcss_tab[ctcss_index_other]);
		}						
		itoa(freq,c,10);
		lcd_cpos(0);
		if(ctcss_index && (freq==0))
		{
			printf_P(PSTR("OFF"));
		}
		else
		{	if (freq == 0)
			{
				c[0]=' ';
				c[1]='O';
				c[2]='F';
				c[3]='F';
			}
			else
			if (freq<1000)
			{
				c[3] = c[2];
				c[2] = '_';
			}
			else
			{
				c[4] = c[3];
				c[3] = '_';
			}
			if(ctcss_index)
			{
				printf_P(PSTR("%s Hz"),c);				
			}
			else{
				if(m_state == CTCSS_SEL_TX)
					printf_P(PSTR("=RX%s"),c);
				else
					printf_P(PSTR("=TX%s"),c);				
			}
		}		
		lcd_fill();
	}

}
Example #15
0
/*-----------------------------------------------------------------------------
*  Ausgang einschalten
*/
void DigOutOn(TDigOutNumber number) {

   TFuncOn fOn = (TFuncOn)pgm_read_word(&sDigOutFuncs[number].fOn);
   fOn();
}
Example #16
0
File: main.c Project: mybays/lm3s
//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void)
{
    //
    // Set the clocking to run directly from the crystal.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_8MHZ);

    //
    // Initialize the OLED display and write status.
    //
    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //PC5,PC7 EN,CSN
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,1<<5|1<<7);

    //SPI配置
    unsigned long ulDataTx[NUM_SSI_DATA];
    unsigned long ulDataRx[NUM_SSI_DATA];
    unsigned long ulindex;
    unsigned long ultemp=0;


    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    GPIOPinConfigure(GPIO_PA4_SSI0RX);
    GPIOPinConfigure(GPIO_PA5_SSI0TX);
    GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
                   GPIO_PIN_2);

    SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                       SSI_MODE_MASTER, 4000000, 8);
    /*
    GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT); 
    GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_4MA,
                     GPIO_PIN_TYPE_STD_WPU);  
    GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_DIR_MODE_OUT);
    GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_0 , GPIO_STRENGTH_4MA,
                     GPIO_PIN_TYPE_STD_WPU);
    */
    SSIEnable(SSI0_BASE);


    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    //
    // Set GPIO A0 and A1 as UART pins.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure the UART for 115,200, 8-N-1 operation.
    //
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));

    //
    // Enable the UART interrupt.
    //
    IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

    //
    // Prompt for text to be entered.
    //
    UARTStdioInit(0);
    UARTSend((unsigned char *)"Enter text:\n\r", 12);
    UARTSend((unsigned char *)"Enter text:\n\r", 12);

    //清零接收缓冲区
    while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
    {
    }
    ulDataTx[0] = 's';
    ulDataTx[1] = 'p';
    ulDataTx[2] = 'i';

    set_nrf24l01_csn_l();
    /*
    for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
    {
    	UARTprintf("'%c' ", ulDataTx[ulindex]);
    	SSIDataPut(SSI0_BASE, ulDataTx[ulindex]);
    }
    */
    set_nrf24l01_csn_h();
    _delay_ms(1);

    if( setDataRate( RF24_250KBPS ) )
    {
        p_variant = true ;
    }

    //初始化NRF24L01
    set_module_tx();
    nrf_write_reg(NRF_CONFIG,0x0a);
    print_byte_register("CONFIG\t",NRF_CONFIG,1);

    init_NRF24L01();
    set_module_tx();

    unsigned char transfer_value[]="EEWORLD_MSP430_00";

    //set_module_tx();

    //读不出来spi数据的原因是,原来里面有没读取完的数据,需要先清理,再读写.



    setChannel(74);
    UARTprintf("getchannel:%d\r\n",getChannel());
 //   setChannel(24);
 //   UARTprintf("getchannel:%d\r\n",getChannel());

    //写地址
    nrf_write_buf(TX_ADDR,(uint8_t*)&addresses[0],5);

    uint8_t recvbuf[5];
    nrf_read_buf(TX_ADDR,&recvbuf[0],5);

    for(int i=0;i<5;i++)
    {
        UARTprintf("%d:%d ",i,recvbuf[i]);
    }
    UARTprintf("\r\n");
    //end of test write address


    uint8_t data[32];

    for(int i=0;i<32;i++)
    {
        data[i]=i;
    }


    

    UARTprintf("\r\n");
    //while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]))
    //{
    //}

    //重新发送前,避免写缓冲区满
    flush_tx();
    spi_write_reg(STATUS, ( spi_read_reg(STATUS) ) | _BV(MAX_RT) );
    //role=role_ping_out
    openWritingPipe(addresses[0]);
    openReadingPipe(1,addresses[1]);

    nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5);

    unsigned char test;
    //while(1)
    {
        test=spi_read_reg(0x05);
        UARTprintf("test:%d\r\n",test);
        _delay_ms(1000);
    }

    //调试关闭
    //nrf_write_reg(EN_AA,0x00);
    nrf_write_reg(EN_RXADDR,0x02);
    //nrf_write_reg(SETUP_RETR,0x00);
    nrf_write_reg(RX_PW_P1,0x20);

    //set_module_tx();
    nrf_write_reg(NRF_CONFIG,0x0b);
    nrf_write_reg(CONFIG, nrf_read_reg(CONFIG) | _BV(PRIM_RX));
    nrf_write_reg(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
    set_nrf24l01_ce_h();
    nrf_write_buf(RX_ADDR_P0,(uint8_t*)&addresses[0],5);
    set_nrf24l01_ce_h();
    if(nrf_read_reg(FEATURE) & _BV(EN_ACK_PAY))
    {
        flush_tx();
    }

    flush_rx();

    print_status(get_status());
    nrf_write_reg(SETUP_AW,0x03);
    print_byte_register("SETUP_AW\t",SETUP_AW,1);
    print_address_register("RX_ADDR_P0-1",RX_ADDR_P0,2);
    print_byte_register("RX_ADDR_P2-5",RX_ADDR_P2,4);

    print_address_register("TX_ADDR\t",TX_ADDR,1);

    print_byte_register("RX_PW_P0-6",RX_PW_P0,6);


    print_byte_register("EN_AA\t",EN_AA,1);
    print_byte_register("EN_RXADDR",EN_RXADDR,1);
    print_byte_register("RF_CH\t",RF_CH,1);
    print_byte_register("RF_SETUP",RF_SETUP,1);

    print_byte_register("CONFIG\t",NRF_CONFIG,1);
    print_byte_register("DYNPD/FEATURE",DYNPD,2);


    UARTprintf("Data Rate\t = %s\r\n", pgm_read_word(&rf24_datarate_e_str_P[getDataRate()]));
    UARTprintf("Model\t\t = %s\r\n",   pgm_read_word(&rf24_model_e_str_P[isPVariant()]));
    UARTprintf("CRC Length\t = %s\r\n",pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()]));
    UARTprintf("PA Power\t = %s\r\n",  pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()]));

    Init_Timer_A();

    set_nrf24l01_ce_h();
    //将业务数据写入:WR_TX_PLOAD

    uint8_t fifo_status,status,state,i;
    while(1)
    {
        fifo_status=spi_read_reg(FIFO_STATUS);
        if(fifo_status&0x02)
        {
            status=spi_read_reg(STATUS);
            if(status&_BV(RX_DR))
            {
                state=spi_send_byte(RD_RX_PLOAD);
                for(i=0;i<RX_PLOAD_WIDTH;i++)
                {
                    status=spi_send_byte(0xff);
                    //buf[i]=status;
                }
                nrf_write_reg(FLUSH_RX,0xFF);
                //UARTprintf(".");
                counter++;
            }
            if(status &0x02)
            {
                nrf_write_reg(FLUSH_RX,0xFF);
                //UARTprintf(".");
                counter++;
            }

            nrf_rx_packet(data);
        }
    }

    while(available(0))
    {
        //UARTprintf(".");
        if(nrf_rx_packet(data) == 0)
        {
            counter++;
        }
        
        //UARTprintf(".");
        //_delay_ms(50);
        /*
        set_nrf24l01_ce_l();
        nrf_write_buf(WR_TX_PLOAD,data,TX_PLOAD_WIDTH);
        set_nrf24l01_ce_h();
        _delay_ms(30);
        */
    }
}
Example #17
0
/*-----------------------------------------------------------------------------
*  Ausgang ausschalten
*/
void DigOutOff(TDigOutNumber number) {

   TFuncOff fOff = (TFuncOff)pgm_read_word(&sDigOutFuncs[number].fOff);
   fOff();
}
Example #18
0
void waves_init()
{
  waves_currentWaveformNumber = 0;
  waves_currentWaveformPointer =
    (uint8_t*)pgm_read_word(&waves_waveformArray[waves_currentWaveformNumber]);
}
Example #19
0
/*-----------------------------------------------------------------------------
*  Ausgang wechseln
*/
void DigOutToggle(TDigOutNumber number) {

   TFuncToggle fToggle = (TFuncToggle)pgm_read_word(&sDigOutFuncs[number].fToggle);
   fToggle();
}
Example #20
0
void Initialize(void){
	int i;

	cli();

	//Initialize I/O registers
	u16 val;
	u8 *ptr;
	for(u8 j=0;j<(sizeof(io_table)>>1);j++){
		val=pgm_read_word(&io_table[j]);
		ptr=(u8*)(val&0xff);
		*ptr=val>>8;
	}

	if(!isEepromFormatted()) FormatEeprom();

	//InitSoundPort(); //ramp-up sound to avoid click

	#if SOUND_MIXER == MIXER_TYPE_VSYNC
	
		//Initialize the mixer buffer
		//ramp up to avoid initial click
		for(int j=0;j<MIX_BANK_SIZE*2;j++){
			mix_buf[j]=0x80;//(i<128?i:128);
		}

		mix_pos=mix_buf;
		mix_bank=0;
	#endif

	#if MIXER_CHAN4_TYPE == 0
		//initialize LFSR		
		tr4_barrel_lo=1;
		tr4_barrel_hi=1;		
		tr4_params=0b00000001; //15 bits no divider (1)
	#endif

	#if UART == 1
		InitUartRxBuffer();
		InitUartTxBuffer();
	#endif

	#if SNES_MOUSE == 1
		snesMouseEnabled=false;
	#endif

	//silence all sound channels
	for(i=0;i<CHANNELS;i++){
		mixer.channels.all[i].volume=0;
	}

	//set sync parameters. starts at odd field, in pre-eq pulses, line 1, vsync flag cleared
	sync_phase=0;
	sync_flags=0;
	sync_pulse=SYNC_PRE_EQ_PULSES+SYNC_EQ_PULSES+SYNC_POST_EQ_PULSES;

	//set rendering parameters
	render_lines_count=FRAME_LINES;
	first_render_line=FIRST_RENDER_LINE;

	joypad1_status_hi=0;
	joypad2_status_hi=0;
	sound_enabled=1;

	InitializeVideoMode();

	sei();

	DisplayLogo();

}
Example #21
0
void __act_setConnected(__ACTUATOR* act,boolean connected){
	// Change the variable
	act->connected = connected;

	// Get the driver class
	const __ACTUATOR_DRIVER_CLASS* driver=act->class;

	// Call the setSpeed method on the class
	if(driver){
		void (*fn)(__ACTUATOR*,boolean connected) = (void (*)(__ACTUATOR*, boolean connected))pgm_read_word(&driver->setConnected);
		if(fn!=null){
			fn(act,connected);
		}
	}
}
Example #22
0
bool TextPainter::UpdateEPDLineData(uint8_t *line_data, uint8_t y_line) {


    bool changed_line = false;

    for (uint8_t i = 0; i < cnt_txt; i++) {  //loop through all text elements

        uint16_t text_y = Text[i].y;
        uint16_t text_x = Text[i].x;
//        uint8_t size = Text[i].size;
#define size 1
        uint16_t x_offset = text_x;

        // one line before and after character will be painted empty for better readability
        if ((y_line == text_y - 1) || (y_line == text_y + FONT_HEIGHT * size + 1)) {
            changed_line = true;
            break;
        }

        // only paint, if text is in relevant area of FONT_HEIGHT
        if ((y_line >= text_y) && (y_line < text_y + FONT_HEIGHT * size)) {

            for (uint8_t s = 0; s < strlen(Text[i].txt); s++) {  //loop through all characters

//                unsigned char txt_to_write = (uint8_t) Text[i].txt[s] - arial_36ptFontInfo.startChar;
                unsigned char txt_to_write = (uint8_t) Text[i].txt[s] - 32;

//                uint8_t *data = (unsigned char *) chrtbl_f32[txt_to_write];
                uint8_t *data = (uint8_t *) pgm_read_word(&chrtbl_f32[txt_to_write]);

//                uint8_t height = arial_36ptDescriptors[txt_to_write].heightBits;
//                uint8_t width = arial_36ptDescriptors[txt_to_write].widthBits;

                uint8_t width = pgm_read_byte(&data[0]);
                uint8_t height = pgm_read_byte(&data[1]);

                // current y-line in the charchater arrya data text to be checked
                int y_char_line = (y_line - text_y - (FONT_HEIGHT - height)) / size;

                // now we are in the line were the real character starts

                if (y_char_line >= 0) {

                    changed_line = true;

/*
                    // RLE decode
                    uint8_t data[500] = {0};
                    EncodeRLE encode;
                    encode.RLEEncoder(txt_to_write, data);
*/
//                  uint8_t *data = (unsigned char *) chrtbl_f32[txt_to_write];


                    // start position in the character data to use to start
                    uint16_t start_pos = (uint8_t) y_char_line * width;

                    uint8_t z = 2; //start with second byte, byte 0 and 1 have hight and width

                    //***************************************************
                    // find the right position in RLE data: Z: number of byte, rle - number of bits to paint

                    uint8_t rle = 0;
                    bool b_black;

                    if (start_pos == 0) {
                        b_black = (bool) (pgm_read_byte(&data[z]) & 0x80);
                        rle = (uint8_t) (pgm_read_byte(&data[z]) & 0x7f);
                    } else {

                        uint16_t rle_pos = (uint16_t) (pgm_read_byte(&data[z]) & 0x7f);

                        while (true) {

                            if (rle_pos > start_pos) {

//                                rle_offset = start_pos - (rle_pos - data_tmp);
//                                rle = data[z]- (start_pos - (rle_pos - data_tmp)); // this is the magic, dont change
//                                rle = data[z] - start_pos + rle_pos - data_tmp; // this is the magic, dont change

                                b_black = (bool) (pgm_read_byte(&data[z]) & 0x80);
                                rle = (uint8_t) (rle_pos - start_pos); // this is the magic, dont change

                                break;
                            };

                            z++;

                            rle_pos = rle_pos + (uint16_t) (pgm_read_byte(&data[z]) & 0x7f);

                        }
                    }

                    //// ********************+ LOOOOP

                    uint8_t x_bit = 0;

                    while (rle != 0) {

                        // pixel must be set
                        if (b_black) {

                            while (rle--) {

                                if (x_bit < width) {
                                    uint16_t bit = x_offset + x_bit;
                                    line_data[bit / 8] = (uint8_t) (line_data[bit / 8] | 1 << ((bit % 8)));
                                    x_bit++;
                                } else {
                                    break;
                                }
                            }

                        } else {

                            x_bit = x_bit + rle;
                            if (x_bit >= width) {
                                break;
                            }
                        }

                        z++;
                        b_black = (bool) (pgm_read_byte(&data[z]) & 0x80);
                        rle = (uint8_t) (pgm_read_byte(&data[z]) & 0x7f);

                    }


                }

                x_offset = x_offset + width * size + 3;
            }
        }


    }

    return changed_line;
}
Example #23
0
char* dayStr(uint8_t day)
{
   strcpy_P(buffer, (PGM_P)pgm_read_word(&(dayNames_P[day])));
   return buffer;
}
Example #24
0
  Serial.print("\r\nLoadUserCode ...");
  while (i<length/dataSize) 
  {
    unsigned short addr, n, val;
    addr = pgm_read_word(&plugin[i++]);
    n = pgm_read_word(&plugin[i++]);
    if (n & 0x8000U) { /* RLE run, replicate n samples */
      n &= 0x7FFF;
      val = pgm_read_word(&plugin[i++]);
      while (n--) {
        Mp3WriteRegister(addr, val>>8, val & 0xff);
      }
    } 
    else {           /* Copy run, copy n samples */
      while (n--) {
        val = pgm_read_word(&plugin[i++]);
        Mp3WriteRegister(addr, val>>8, val & 0xff);
      }
    }
  }
  Serial.println("over!");
}


const unsigned short linToDBTab[5] = {
  36781, 41285, 46341, 52016, 58386};

/*
  Converts a linear 16-bit value between 0..65535 to decibels.
 Reference level: 32768 = 96dB (largest VS1053 number is 32767 = 95dB).
 Bugs:
Example #25
0
/***********************************************************************************
 **** CMD FUNCTION ENTRY POINTS ****************************************************
 ***********************************************************************************
 * Primary access points to cmd functions
 * These gatekeeper functions check index ranges so others don't have to
 *
 * cmd_print()	- Output a formatted string for the value.
 */
void cmd_print(cmdObj_t *cmd)
{
//	if (cmd->index >= CMD_INDEX_MAX) return;
	((fptrPrint)(pgm_read_word(&cfgArray[cmd->index].print)))(cmd);
}
void Enemy::draw(){
    gb.display.drawBitmap(x-3, y-3, (const byte*)pgm_read_word(&(enemy_types[type*3])));
}
Example #27
0
uint8_t HTMLParser::Parsing_Get(char *buf)
{
	uint8_t i, index = 0;
	uint8_t tmpbuf[16], msgbuf[10];
	uint8_t retval = 0;

	memset(tmpbuf, 0, 16);
	
	for(i=0; i<6; i++)
		tmpbuf[i] = buf[i];

	Serial.println((char *)tmpbuf);
	
	memset(msgbuf, 0, 10);
       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[0]))); // Necessary casts and dereferencing, just copy. 
//	Serial.println((char *)msgbuf);
	
	if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
	{
		memset(tmpbuf, 0, 16);
		index = 0;
		
		for(; buf[i] != '='; i++)
		{
			Serial.print((char)buf[i]);
			tmpbuf[index++] = buf[i];
		}
		i++;
		
		Serial.println((char *)tmpbuf);
	
		memset(msgbuf, 0, 10);
	       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[1]))); // Necessary casts and dereferencing, just copy. 
		
		if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
		{
			memset(tmpbuf, 0, 16);
			index = 0;
			
			for(; buf[i] != ' '; i++)
			{
				Serial.print((char)buf[i]);
				tmpbuf[index++] = buf[i];
			}

			Serial.println((char *)tmpbuf);

			memset(msgbuf, 0, 10);
		       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[2]))); // Necessary casts and dereferencing, just copy. 
			if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
			{
				myParam.VALUE = FW_CMD;
				Serial.println((char *)msgbuf);
				return 1;
			}

			memset(msgbuf, 0, 10);
		       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[3]))); // Necessary casts and dereferencing, just copy. 
			if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
			{
				myParam.VALUE = BW_CMD;
				Serial.println((char *)msgbuf);
				return 1;
			}

			memset(msgbuf, 0, 10);
		       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[4]))); // Necessary casts and dereferencing, just copy. 
			if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
			{
				myParam.VALUE = RT_CMD;
				Serial.println((char *)msgbuf);
				return 1;
			}

			memset(msgbuf, 0, 10);
		       strcpy_P((char *)msgbuf, (char*)pgm_read_word(&(CMDMsg_table[5]))); // Necessary casts and dereferencing, just copy. 
			if(!strcmp((const char*)tmpbuf, (const char*)msgbuf))
			{
				myParam.VALUE = LF_CMD;
				Serial.println((char *)msgbuf);
				return 1;
			}

			myParam.VALUE = NO_CMD;
		}
	}else
		return 0;
}
void Enemy::move(){
    const byte *ref = (const byte*)pgm_read_word(&(enemy_types[type*3+1]));
    uint8_t frame = gb.frameCount % (uint8_t )pgm_read_byte(&(ref[0]));
    x += (int8_t) pgm_read_byte(&(ref[frame*2+1]));
    y += (int8_t) pgm_read_byte(&(ref[frame*2+2]));
}
	//*******************************************************************************
	void	GetFontDef_Astrology(short tableIndex, char *fontDefString)
	{
		strcpy_P(fontDefString, (char*)pgm_read_word(&(gHershyAstrologyFontTable[tableIndex])));
	}
Example #30
0
void ProcessMusic(void){
	u8 c1,c2,tmp,trackVol;
	s16 vol;
	u16 uVol,tVol;
	u8 channel;
	struct TrackStruct* track;


	//process patches envelopes & pitch slides
	for(unsigned char trackNo=0;trackNo<CHANNELS;trackNo++){
		track=&tracks[trackNo];

		//update envelope
		if(track->envelopeStep!=0){
			vol=track->envelopeVol+track->envelopeStep;		
			if(vol<0){
				vol=0;			
			}else if(vol>0xff){
				vol=0xff;						
			}
			track->envelopeVol=vol;
		}
	
		if(track->flags & TRACK_FLAGS_SLIDING){

			mixer.channels.all[trackNo].step+=track->slideStep;
			u16 tStep=pgm_read_word(&(steptable[track->slideNote]));

			if((track->slideStep>0 && mixer.channels.all[trackNo].step>=tStep) || 
				(track->slideStep<0 && mixer.channels.all[trackNo].step<=tStep))
			{					
				mixer.channels.all[trackNo].step = tStep;					
				track->flags &= ~(TRACK_FLAGS_SLIDING);	
			}
		}
	}



	//Process song MIDI notes
	if(playSong){
	
		#if MUSIC_ENGINE == MIDI
			
			//process all simultaneous events
			while(currDeltaTime==nextDeltaTime){

				c1=pgm_read_byte(songPos++);
			
				if(c1==0xff){
					//META data type event
					c1=pgm_read_byte(songPos++);

				
					if(c1==0x2f){ //end of song
						playSong=false;
						break;	
					}else if(c1==0x6){ //marker
						c1=pgm_read_byte(songPos++); //read len
						c2=pgm_read_byte(songPos++); //read data
						if(c2=='S'){ //loop start
							loopStart=songPos;
						}else if(c2=='E'){//loop end
							songPos=loopStart;
						}
					}
				

				}else{

					if(c1&0x80) lastStatus=c1;					
					channel=lastStatus&0x0f;
				
					//get next data byte
					//Note: maybe we should not advance the cursor
					//in case we receive an unsupported command				
					if(c1&0x80) c1=pgm_read_byte(songPos++); 

					switch(lastStatus&0xf0){

						//note-on
						case 0x90:
							//c1 = note						
							c2=pgm_read_byte(songPos++)<<1; //get volume
						
							if(tracks[channel].flags|TRACK_FLAGS_ALLOCATED){ //allocated==true
								TriggerNote(channel,tracks[channel].patchNo,c1,c2);
							}
							break;

						//controllers
						case 0xb0:
							///c1 = controller #
							c2=pgm_read_byte(songPos++); //get controller value
						
							if(c1==CONTROLER_VOL){
								tracks[channel].trackVol=c2<<1;
							}else if(c1==CONTROLER_EXPRESSION){
								tracks[channel].expressionVol=c2<<1;
							}else if(c1==CONTROLER_TREMOLO){
								tracks[channel].tremoloLevel=c2<<1;
							}else if(c1==CONTROLER_TREMOLO_RATE){
								tracks[channel].tremoloRate=c2<<1;
							}
						
							break;

						//program change
						case 0xc0:
							// c1 = patch #						
							tracks[channel].patchNo=c1;
							break;

					}//end switch(c1&0xf0)


				}//end if(c1==0xff)

				//read next delta time
				nextDeltaTime=ReadVarLen(&songPos);			
				currDeltaTime=0;
		
				#if SONG_SPEED == 1
					if(songSpeed != 0){
						uint32_t l  = (uint32_t)(nextDeltaTime<<8);

						if(songSpeed < 0){//slower
							(uint32_t)(l += (uint32_t)(-songSpeed*(nextDeltaTime<<1)));
							(uint32_t)(l >>= 8);
						}
						else//faster
							(uint32_t)(l /= (uint32_t)((1<<8)+(songSpeed<<1)));

						nextDeltaTime = l;
					}