diff --git a/firmware/apps/tuner.c b/firmware/apps/tuner.c index c2b4c91..2f6a5ed 100644 --- a/firmware/apps/tuner.c +++ b/firmware/apps/tuner.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "api.h" //Draws the codeplug name. @@ -53,8 +54,52 @@ int tuner_exit(){ static int vfosetmode=0; static int rssi=0x5; +static void clearperiods(){ + int i; + for(i=0; i<8; i++) + setperiod(i,0); +} + +int vfosetmode_bufferi; +char vfosetmode_buffer[9]; + +static void vfosetmode_apply(){ + long f=atol(vfosetmode_buffer); + + vfosetmode=0; + printf("Setting frequency to %ld\n",f); + codeplug_setvfofreq((float) f); +} + +static void vfosetmode_keypress(char ch){ + //Numbers populate a buffer character. + if(ch>='0' && ch<='9') + vfosetmode_buffer[vfosetmode_bufferi++]=ch; + + //Exit when we have all characters or = is pressed again. + if(ch=='=' || vfosetmode_bufferi==8){ + vfosetmode_apply(); + } +} + +static void vfosetmode_draw(){ + /* This is called four times a second when we are setting the VFO + frequency. Activate the mode by pressing the = button. + */ + clearperiods(); + lcd_string(vfosetmode_buffer); + setperiod(5,1); + setperiod(2,1); +} + + //! Tuner keypress callback. int tuner_keypress(char ch){ + if(vfosetmode){ + vfosetmode_keypress(ch); + return 0; + } + switch(ch){ default: draw(); @@ -69,11 +114,12 @@ int tuner_keypress(char ch){ break; case '/': //Show the frequency. lcd_number(codeplug_getfreq()/10); - //setperiod(5,1); //Periods are controlled by RSSI right now. - //setperiod(2,1); break; - case '=': //Set a frequency. Not yet working. - vfosetmode=!vfosetmode; + case '=': //Set a VFO frequency. + vfosetmode=1; + //Clear all eight digits, plus null terminator. + memset(vfosetmode_buffer,'0',9); + vfosetmode_bufferi=0; break; case '7': //Show snapshot of scalar RSSI. lcd_number(rssi); @@ -84,16 +130,17 @@ int tuner_keypress(char ch){ return 1;//Redraw. } -void clearperiods(){ - int i; - for(i=0; i<8; i++) - setperiod(i,0); -} //! Draw the screen and increase the count. void tuner_draw(){ static int i=0; + //No sense using the radio when we don't yet know the frequency. + if(vfosetmode){ + vfosetmode_draw(); + return; + } + /* Every other frame, we grab the signal strength. Highest stays. */ if(!(i&1)) diff --git a/firmware/codeplug.c b/firmware/codeplug.c index 81c7b5c..90f66dd 100644 --- a/firmware/codeplug.c +++ b/firmware/codeplug.c @@ -14,30 +14,32 @@ //! Array of codeplug entries in info flash. struct codeplugentry *codeplug = (struct codeplugentry*) 0x1800; +static struct codeplugentry *selectedentry; + +//! Special codeplug entry for the VFO. +struct codeplugentry vfoentry={ + .flags=0x00, + .name="vfo mode" +}; + //! Index of entry in the codeplug. -static unsigned int codeplugi=0; +static int codeplugi=0; //! Initialize the codeplug at boot. void codeplug_init(){ do{ - /* - printf("Codeplug entry '%s': %02x 0x%02x%02x%02x\n", - codeplug_name(), - codeplug[codeplugi].flags, - codeplug[codeplugi].freq2, - codeplug[codeplugi].freq1, - codeplug[codeplugi].freq0 - ); - */ codeplug_next(); }while(codeplugi); - + + selectedentry = &codeplug[codeplugi]; } //! Next codeplug entry. void codeplug_next(){ if(codeplug[++codeplugi].flags==0xFF) codeplugi=0; + + selectedentry = &codeplug[codeplugi]; } //! Previous codeplug entry. @@ -51,14 +53,16 @@ void codeplug_prev(){ //Jump back one. codeplugi--; } + + selectedentry = &codeplug[codeplugi]; } //! Return the name of the codeplug entry. 8 bytes, no null terminator! const char *codeplug_name(){ static char name[9]; - if(codeplug[codeplugi].flags!=0xFF){ - memcpy(name,codeplug[codeplugi].name,8); + if(selectedentry->flags!=0xFF){ + memcpy(name,selectedentry->name,8); name[8]=0; }else{ /* We don't seem to have a codeplug, so we write "Missing" to the @@ -72,29 +76,44 @@ const char *codeplug_name(){ //! Sets the codeplug frequency. void codeplug_setfreq(){ - if(codeplug[codeplugi].flags!=0xFF){ + if(selectedentry->flags!=0xFF){ /* We have a codeplug, so set the current entry's frequency. */ - radio_setrawfreq(codeplug[codeplugi].freq2, - codeplug[codeplugi].freq1, - codeplug[codeplugi].freq0); + radio_setrawfreq(selectedentry->freq2, + selectedentry->freq1, + selectedentry->freq0); }else{ /* We don't have a codeplug, so default to 434.0 */ radio_setfreq(434000000); } } +//! Sets the VFO frequency. +void codeplug_setvfofreq(float freq){ + float freqMult = (0x10000 / 1000000.0) / 26; + uint32_t num = freq * freqMult; + + //Store the frequency into the VFO entry. + vfoentry.freq2 = (num >> 16) & 0xFF; + vfoentry.freq1 = (num >> 8) & 0xFF; + vfoentry.freq0 = num & 0xFF; + + //Select the VFO entry. + selectedentry = &vfoentry; + + //Tune the radio. + codeplug_setfreq(); +} + + //! Gets the codeplug frequency. uint32_t codeplug_getfreq(){ static uint32_t oldhex=0, oldnum=0; uint32_t hex= - 0xFF0000l & (((uint32_t) codeplug[codeplugi].freq2)<<16); - hex|= (0xFF00l & (codeplug[codeplugi].freq1<<8)); - hex|= (0xFFl & (codeplug[codeplugi].freq0)); - - - + 0xFF0000l & (((uint32_t) selectedentry->freq2)<<16); + hex|= (0xFF00l & (selectedentry->freq1<<8)); + hex|= (0xFFl & (selectedentry->freq0)); - if(codeplug[codeplugi].flags!=0xFF){ + if(selectedentry->flags!=0xFF){ /* We have a codeplug, so set the current entry's frequency. */ //Return the old value if it hasn't changed. diff --git a/firmware/codeplug.h b/firmware/codeplug.h index 52492fc..09f26c4 100644 --- a/firmware/codeplug.h +++ b/firmware/codeplug.h @@ -17,9 +17,9 @@ struct codeplugentry { /* The frequency is stored in the CC1101-based radio's internal format. See radio.c for example calculations. */ - const uint8_t freq2; - const uint8_t freq1; - const uint8_t freq0; + uint8_t freq2; + uint8_t freq1; + uint8_t freq0; /* The eight character name is *NOT* null terminated. */ const char name[8]; @@ -37,4 +37,6 @@ void codeplug_setfreq(); //! Gets the codeplug frequency. uint32_t codeplug_getfreq(); +//! Sets the VFO frequency. +void codeplug_setvfofreq(float freq);