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]))); }
//////////////////////////////////////////////////////////////////////////////////////////////////// //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; }
char* monthStr(uint8_t month) { strcpy_P(buffer, (PGM_P)pgm_read_word(&(monthNames_P[month]))); return buffer; }
/***************************************************************************** * 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); }
/*----------------------------------------------------------------------------- * Ausgangszustand lesen */ BOOL DigOutState(TDigOutNumber number) { TFuncState fState = (TFuncState)pgm_read_word(&sDigOutFuncs[number].fState); return fState(); }
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; }
//-------------------------------------------------------------------- //[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; }
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]))); }
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; }
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; }
const char* pin_def_t::get_name_P(void) const { return reinterpret_cast<const char*>(pgm_read_word(&name)); }
bool pin_def_t::is_valid_P(void) const { return pgm_read_word(&name) != 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(); } }
/*----------------------------------------------------------------------------- * Ausgang einschalten */ void DigOutOn(TDigOutNumber number) { TFuncOn fOn = (TFuncOn)pgm_read_word(&sDigOutFuncs[number].fOn); fOn(); }
//***************************************************************************** // // 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); */ } }
/*----------------------------------------------------------------------------- * Ausgang ausschalten */ void DigOutOff(TDigOutNumber number) { TFuncOff fOff = (TFuncOff)pgm_read_word(&sDigOutFuncs[number].fOff); fOff(); }
void waves_init() { waves_currentWaveformNumber = 0; waves_currentWaveformPointer = (uint8_t*)pgm_read_word(&waves_waveformArray[waves_currentWaveformNumber]); }
/*----------------------------------------------------------------------------- * Ausgang wechseln */ void DigOutToggle(TDigOutNumber number) { TFuncToggle fToggle = (TFuncToggle)pgm_read_word(&sDigOutFuncs[number].fToggle); fToggle(); }
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(); }
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); } } }
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; }
char* dayStr(uint8_t day) { strcpy_P(buffer, (PGM_P)pgm_read_word(&(dayNames_P[day]))); return buffer; }
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:
/*********************************************************************************** **** 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]))); }
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]))); }
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; }