diff --git a/Arduino-microfox/Arduino-microfox.ino b/Arduino-microfox/Arduino-microfox.ino index 0d81f06..8965053 100644 --- a/Arduino-microfox/Arduino-microfox.ino +++ b/Arduino-microfox/Arduino-microfox.ino @@ -72,6 +72,9 @@ volatile int g_startclock_interval = 60; volatile BOOL g_audio_tone_on = FALSE; volatile uint8_t g_lastSeconds = 0x00; +volatile int16_t g_sync_pin_timer = 0; +volatile BOOL g_sync_pin_stable = FALSE; +volatile BOOL g_sync_enabled = TRUE; #ifndef COMPILE_FOR_ATMELSTUDIO7 FoxType& operator++ (FoxType & orig) @@ -136,7 +139,6 @@ static uint16_t EEMEM ee_ID_time; static uint16_t EEMEM ee_clock_calibration; static uint8_t EEMEM ee_override_DIP_switches; static uint8_t EEMEM ee_enable_LEDs; -static uint8_t EEMEM ee_enable_sync; static int16_t EEMEM ee_temp_calibration; static uint8_t EEMEM ee_enable_start_timer; @@ -149,13 +151,10 @@ static volatile uint16_t g_clock_calibration = EEPROM_CLOCK_CALIBRATION_DEFAULT; static volatile int16_t g_temp_calibration = EEPROM_TEMP_CALIBRATION_DEFAULT; static volatile uint8_t g_override_DIP_switches = EEPROM_OVERRIDE_DIP_SW_DEFAULT; static volatile uint8_t g_enable_LEDs; -static volatile uint8_t g_enable_sync; static volatile uint8_t g_enable_start_timer; static char g_tempStr[TEMP_STRING_LENGTH] = { '\0' }; -static volatile uint8_t g_start_override = FALSE; - /* * Function Prototypes */ @@ -168,6 +167,7 @@ void setUpTemp(void); void sendMorseTone(BOOL onOff); void playStartingTone(uint8_t toneFreq); void wdt_init(WDReset resetType); +void doSynchronization(void); #ifdef COMPILE_FOR_ATMELSTUDIO7 void loop(void); @@ -178,7 +178,7 @@ void wdt_init(WDReset resetType); { while(initializeEEPROMVars()) { - ; /* Initialize variables stored in EEPROM */ + ; /* Initialize variables stored in EEPROM */ } setUpTemp(); @@ -186,26 +186,26 @@ void wdt_init(WDReset resetType); cli(); /*stop interrupts for setup */ /* set pins as outputs */ - pinMode(PIN_NANO_LED, OUTPUT); /* The nano amber LED: This led blinks when off cycle and blinks with code when on cycle. */ - digitalWrite(PIN_NANO_LED, OFF); - pinMode(PIN_NANO_KEY, OUTPUT); /* This pin is used to control the KEY line to the transmittter only active on cycle. */ - digitalWrite(PIN_NANO_KEY, OFF); + pinMode(PIN_LED, OUTPUT); /* The nano amber LED: This led blinks when off cycle and blinks with code when on cycle. */ + digitalWrite(PIN_LED, OFF); + pinMode(PIN_MORSE_KEY, OUTPUT); /* This pin is used to control the KEY line to the transmittter only active on cycle. */ + digitalWrite(PIN_MORSE_KEY, OFF); pinMode(PIN_AUDIO_OUT, OUTPUT); digitalWrite(PIN_AUDIO_OUT, OFF); #if !HARDWARE_EXTERNAL_DIP_PULLUPS_INSTALLED - pinMode(PIN_NANO_SYNC, INPUT_PULLUP); /* Sync button */ - pinMode(PIN_NANO_DIP_0, INPUT_PULLUP); /* DIP switch LSB */ - pinMode(PIN_NANO_DIP_1, INPUT_PULLUP); /* DIP switch middle bit */ - pinMode(PIN_NANO_DIP_2, INPUT_PULLUP); /* DIP switch MSB */ + pinMode(PIN_SYNC, INPUT_PULLUP); /* Sync button */ + pinMode(PIN_DIP_0, INPUT_PULLUP); /* DIP switch LSB */ + pinMode(PIN_DIP_1, INPUT_PULLUP); /* DIP switch middle bit */ + pinMode(PIN_DIP_2, INPUT_PULLUP); /* DIP switch MSB */ #else - pinMode(PIN_NANO_SYNC, INPUT); /* Sync button */ - pinMode(PIN_NANO_DIP_0, INPUT); /* DIP switch LSB */ - pinMode(PIN_NANO_DIP_1, INPUT); /* DIP switch middle bit */ - pinMode(PIN_NANO_DIP_2, INPUT); /* DIP switch MSB */ + pinMode(PIN_SYNC, INPUT); /* Sync button */ + pinMode(PIN_DIP_0, INPUT); /* DIP switch LSB */ + pinMode(PIN_DIP_1, INPUT); /* DIP switch middle bit */ + pinMode(PIN_DIP_2, INPUT); /* DIP switch MSB */ #endif /* HARDWARE_EXTERNAL_DIP_PULLUPS_INSTALLED */ - digitalWrite(PIN_NANO_LED, OFF); /* Turn off led sync switch is now open */ + digitalWrite(PIN_LED, OFF); /* Turn off led sync switch is now open */ /* set timer1 interrupt at 1Hz */ TCCR1A = 0; /* set entire TCCR1A register to 0 */ @@ -248,17 +248,22 @@ void wdt_init(WDReset resetType); /* Timer 0 is for audio Start tone generation and control * Note: Do not use millis() or DELAY() after TIMER0 has been reconfigured here! */ TCCR0A = 0x00; -/* TCCR0A |= (1 << COM0A0) | (1 << WGM01); / * Set toggle OC0A, CTC mode * / */ - TCCR0A |= (1 << WGM01); /* Set CTC mode */ + TCCR0A |= (1 << WGM01); /* Set CTC mode */ TCCR0B = 0x00; - TCCR0B |= (1 << CS02); /* Prescale 256 */ + TCCR0B |= (1 << CS02); /* Prescale 256 */ OCR0A = DEFAULT_TONE_FREQUENCY; TIMSK0 = 0x00; TIMSK0 |= (1 << OCIE0A); - sei(); /*allow interrupts. Arm and run */ + /* Sync button pin change interrupt */ + PCMSK2 = 0x00; + PCMSK2 = (1 << PCINT19); /* Enable PCINT19 */ + PCICR = 0x00; + PCICR = (1 << PCIE2); /* Enable pin change interrupt 2 */ - linkbus_init(BAUD); /* Start the Link Bus serial comms */ + sei(); /*allow interrupts. Arm and run */ + + linkbus_init(BAUD); /* Start the Link Bus serial comms */ lb_send_string((char*)"\n\nStored Data:\n", TRUE); sprintf(g_tempStr, " ID: %s\n", g_messages_text[STATION_ID]); @@ -269,8 +274,6 @@ void wdt_init(WDReset resetType); lb_send_string(g_tempStr, TRUE); sprintf(g_tempStr, " LED: %s\n", g_enable_LEDs ? "ON" : "OFF"); lb_send_string(g_tempStr, TRUE); - sprintf(g_tempStr, " SYN: %s\n", g_enable_sync ? "ON" : "OFF"); - lb_send_string(g_tempStr, TRUE); sprintf(g_tempStr, " STA: %s\n", g_enable_start_timer ? "ON" : "OFF"); lb_send_string(g_tempStr, TRUE); lb_send_NewPrompt(); @@ -285,62 +288,28 @@ void wdt_init(WDReset resetType); } else /* Read DIP Switches */ { - if(digitalRead(PIN_NANO_DIP_0) == LOW) /*Lsb */ + if(digitalRead(PIN_DIP_0) == LOW) /*Lsb */ { g_fox++; } - if(digitalRead(PIN_NANO_DIP_1) == LOW) /* middle bit */ + if(digitalRead(PIN_DIP_1) == LOW) /* middle bit */ { g_fox += 2; } - if(digitalRead(PIN_NANO_DIP_2) == LOW) /* MSB */ + if(digitalRead(PIN_DIP_2) == LOW) /* MSB */ { g_fox += 4; } } -/* - * we now look at the sync line and then reset the time counters - * when the sync switch is released. - * */ - if(g_enable_sync && (g_enable_start_timer || ((g_fox != FOXORING) && (g_fox != BEACON) && (g_fox != FOX_DEMO) && (g_fox != SPRINT_DEMO) && (g_fox != SPECTATOR)))) - { - lb_send_string((char*)"Waiting for sync.\n", TRUE); - lb_send_string((char*)"Type \"GO\"\n", TRUE); - lb_send_NewPrompt(); - - while(( digitalRead(PIN_NANO_SYNC) == LOW) && !g_start_override) - { - if(g_enable_LEDs) - { - digitalWrite(PIN_NANO_LED, HIGH); /* arduino nano LED turn on led to show sync switch is closed */ - } - - handleLinkBusMsgs(); - } - } - else - { - lb_send_string((char*)"Tx is running!\n", TRUE); - lb_send_NewPrompt(); - } - - TCNT1 = 0; /* Initialize 1-second counter value to 0 */ - g_seconds_since_sync = 0; - g_fox_seconds_into_interval = 0; - - g_start_override = TRUE; - #if !HARDWARE_EXTERNAL_DIP_PULLUPS_INSTALLED /* Disable pull-ups to save power */ - pinMode(PIN_NANO_SYNC, INPUT); /* Sync button input */ - pinMode(PIN_NANO_DIP_0, INPUT); /* fox switch LSB */ - pinMode(PIN_NANO_DIP_1, INPUT); /* fox switch middle bit */ - pinMode(PIN_NANO_DIP_2, INPUT); /* fox switch MSB */ - pinMode(PIN_NANO_SYNC, OUTPUT); - pinMode(PIN_NANO_DIP_0, OUTPUT); - pinMode(PIN_NANO_DIP_1, OUTPUT); - pinMode(PIN_NANO_DIP_2, OUTPUT); + pinMode(PIN_DIP_0, INPUT); /* fox switch LSB */ + pinMode(PIN_DIP_1, INPUT); /* fox switch middle bit */ + pinMode(PIN_DIP_2, INPUT); /* fox switch MSB */ + pinMode(PIN_DIP_0, OUTPUT); + pinMode(PIN_DIP_1, OUTPUT); + pinMode(PIN_DIP_2, OUTPUT); #endif /* HARDWARE_EXTERNAL_DIP_PULLUPS_INSTALLED */ if((g_fox == BEACON) || (g_fox == SPECTATOR)) @@ -424,6 +393,28 @@ void __attribute__((optimize("O1"))) wdt_init(WDReset resetType) } +/*********************************************************************** + * Pin Change Interrupt 2 ISR + * + * Handles SYNC pin operation + * + ************************************************************************/ +ISR(PCINT2_vect) +{ + BOOL pinVal = digitalRead(3); + + if(pinVal) /* Sync is high */ + { + if(g_sync_pin_stable) + { + doSynchronization(); + } + } + + g_sync_pin_timer = 0; +} + + /*********************************************************************** * Watchdog Timeout ISR * @@ -708,6 +699,23 @@ ISR( TIMER2_COMPB_vect ) static BOOL playMorse = TRUE; BOOL repeat = TRUE, finished = FALSE; + if(g_sync_enabled) + { + if(digitalRead(PIN_SYNC) == LOW) + { + if(g_sync_pin_timer < TIMER2_SECONDS_3) + { + g_sync_pin_timer++; + } + + if(g_sync_pin_timer > TIMER2_SECONDS_1) + { + g_sync_pin_stable = TRUE; + digitalWrite(PIN_LED, HIGH); + } + } + } + if(blink_counter < -BLINK_LONG) { blink_count_direction = 1; @@ -812,10 +820,10 @@ ISR( TIMER2_COMPB_vect ) { if(g_enable_LEDs) { - digitalWrite(PIN_NANO_LED, HIGH); /* Nano LED */ + digitalWrite(PIN_LED, HIGH); /* LED */ } - digitalWrite(PIN_NANO_KEY, HIGH); /* TX key line */ + digitalWrite(PIN_MORSE_KEY, HIGH); /* TX key line */ } if(playMorse) @@ -826,12 +834,12 @@ ISR( TIMER2_COMPB_vect ) } else { - if(g_enable_LEDs) + if(g_enable_LEDs && !g_sync_pin_stable) { - digitalWrite(PIN_NANO_LED, key); /* nano LED */ + digitalWrite(PIN_LED, key); /* LED */ } - digitalWrite(PIN_NANO_KEY, key); /* TX key line */ + digitalWrite(PIN_MORSE_KEY, key); /* TX key line */ codeInc = g_code_throttle; if(playMorse) { @@ -844,8 +852,11 @@ ISR( TIMER2_COMPB_vect ) if(key) { key = OFF; - digitalWrite(PIN_NANO_LED, LOW); /* nano LED */ - digitalWrite(PIN_NANO_KEY, LOW); /* TX key line */ + if(!g_sync_pin_stable) + { + digitalWrite(PIN_LED, LOW); /* LED Off */ + } + digitalWrite(PIN_MORSE_KEY, LOW); /* TX key line */ } if(playMorse) @@ -893,6 +904,15 @@ ISR(TIMER1_COMPA_vect) /*timer1 interrupt 1Hz */ if(g_fox_counter > g_number_of_foxes) { g_fox_counter = 1; + + if(g_sync_enabled) + { + PCMSK2 &= ~(1 << PCINT19); /* Disable PCINT19 */ + PCICR &= ~(1 << PCIE2); /* Disable pin change interrupt 2 */ + pinMode(PIN_SYNC, INPUT); + pinMode(PIN_SYNC, OUTPUT); /* Set sync pin as output low */ + g_sync_enabled = FALSE; + } } g_fox_transition = TRUE; g_fox_seconds_into_interval = 0; @@ -1002,11 +1022,14 @@ void loop() { if(g_blinky_time) { - digitalWrite(PIN_NANO_LED,OFF); + if(!g_sync_pin_stable) + { + digitalWrite(PIN_LED,OFF); + } } else { - digitalWrite(PIN_NANO_LED,ON); + digitalWrite(PIN_LED,ON); } } } @@ -1244,27 +1267,6 @@ void __attribute__((optimize("O0"))) handleLinkBusMsgs() } break; - case MESSAGE_SYNC_ENABLE: - { - if(lb_buff->fields[FIELD1][0]) - { - if((lb_buff->fields[FIELD1][1] == 'F') || (lb_buff->fields[FIELD1][0] == '0')) - { - g_enable_sync = FALSE; - } - else - { - g_enable_sync = TRUE; - } - - saveAllEEPROM(); - } - - sprintf(g_tempStr,"SYN:%s\n",g_enable_sync ? "ON" : "OFF"); - lb_send_string(g_tempStr,FALSE); - } - break; - case MESSAGE_STARTTONES_ENABLE: { if(lb_buff->fields[FIELD1][0]) @@ -1288,21 +1290,8 @@ void __attribute__((optimize("O0"))) handleLinkBusMsgs() case MESSAGE_GO: { - if(g_start_override) - { - lb_send_string((char*)"Re-sync successful!\n",FALSE); - } - else - { - g_start_override = TRUE; - lb_send_string((char*)"Running!\n",FALSE); - } - - cli(); - TCNT1 = 0; /* Initialize 1-second counter value to 0 */ - g_seconds_since_sync = 0; - g_fox_seconds_into_interval = 0; - sei(); + doSynchronization(); + lb_send_string((char*)"Re-sync successful!\n",FALSE); } break; @@ -1450,7 +1439,7 @@ void __attribute__((optimize("O0"))) handleLinkBusMsgs() } float temp = 10. * getTemp(); - sprintf(g_tempStr,"Temp: %d.%dC\n",(int)temp / 10,(int)temp % 10); + sprintf(g_tempStr,"Temp: %d.%dC\n",(int)temp / 10,abs((int)temp % 10)); lb_send_string(g_tempStr,FALSE); } break; @@ -1488,7 +1477,6 @@ BOOL initializeEEPROMVars() g_temp_calibration = (int16_t)eeprom_read_word((uint16_t*)&ee_temp_calibration); g_override_DIP_switches = eeprom_read_byte(&ee_override_DIP_switches); g_enable_LEDs = eeprom_read_byte(&ee_enable_LEDs); - g_enable_sync = eeprom_read_byte(&ee_enable_sync); g_enable_start_timer = eeprom_read_byte(&ee_enable_start_timer); for(i = 0; i < 20; i++) @@ -1519,7 +1507,6 @@ BOOL initializeEEPROMVars() g_temp_calibration = EEPROM_TEMP_CALIBRATION_DEFAULT; g_override_DIP_switches = EEPROM_OVERRIDE_DIP_SW_DEFAULT; g_enable_LEDs = EEPROM_ENABLE_LEDS_DEFAULT; - g_enable_sync = EEPROM_ENABLE_SYNC_DEFAULT; g_enable_start_timer = EEPROM_ENABLE_STARTTIMER_DEFAULT; strncpy(g_messages_text[STATION_ID],EEPROM_STATION_ID_DEFAULT,MAX_PATTERN_TEXT_LENGTH); strncpy(g_messages_text[PATTERN_TEXT],EEPROM_PATTERN_TEXT_DEFAULT,MAX_PATTERN_TEXT_LENGTH); @@ -1549,7 +1536,6 @@ void saveAllEEPROM() eeprom_update_word((uint16_t*)&ee_temp_calibration,(uint16_t)g_temp_calibration); eeprom_update_byte(&ee_override_DIP_switches,g_override_DIP_switches); eeprom_update_byte(&ee_enable_LEDs,g_enable_LEDs); - eeprom_update_byte(&ee_enable_sync,g_enable_sync); eeprom_update_byte(&ee_enable_start_timer,g_enable_start_timer); for(i = 0; i < strlen(g_messages_text[STATION_ID]); i++) @@ -1626,9 +1612,24 @@ uint16_t readADC() */ float getTemp(void) { - float offset = (float)g_temp_calibration / 10.; + float offset = CLAMP(-200.,(float)g_temp_calibration / 10.,200.); /* The offset (first term) was determined empirically */ readADC(); /* throw away first reading */ return(offset + (readADC() - 324.31) / 1.22); } + + +void doSynchronization(void) +{ + cli(); + TCNT1 = 0; /* Initialize 1-second counter value to 0 */ + g_seconds_since_sync = 0; + g_fox_seconds_into_interval = 0; + g_sync_pin_stable = FALSE; + digitalWrite(PIN_LED,LOW); + g_on_the_air = 0; + g_fox_counter = 1; /* Don't count on the 1-sec timer setting this in time */ + sei(); +} + diff --git a/Arduino-microfox/defs.h b/Arduino-microfox/defs.h index b8453cb..490dd0a 100644 --- a/Arduino-microfox/defs.h +++ b/Arduino-microfox/defs.h @@ -61,7 +61,7 @@ /****************************************************** * Set the text that gets displayed to the user */ -#define SW_REVISION "0.11" +#define SW_REVISION "0.13" //#define TRANQUILIZE_WATCHDOG @@ -89,12 +89,12 @@ typedef unsigned char uint8_t; #define null 0 #endif -#define PIN_NANO_LED 13 -#define PIN_NANO_KEY 2 -#define PIN_NANO_SYNC 3 -#define PIN_NANO_DIP_0 4 -#define PIN_NANO_DIP_1 5 -#define PIN_NANO_DIP_2 6 +#define PIN_LED 13 +#define PIN_MORSE_KEY 2 +#define PIN_SYNC 3 +#define PIN_DIP_0 4 +#define PIN_DIP_1 5 +#define PIN_DIP_2 6 #define PIN_AUDIO_OUT 9 typedef enum { @@ -141,7 +141,7 @@ typedef enum /****************************************************** * EEPROM definitions */ -#define EEPROM_INITIALIZED_FLAG 0xB3 +#define EEPROM_INITIALIZED_FLAG 0xB4 #define EEPROM_UNINITIALIZED 0x00 #define EEPROM_STATION_ID_DEFAULT "FOXBOX" @@ -160,25 +160,8 @@ typedef enum #define EEPROM_TEMP_CALIBRATION_DEFAULT 147 #define EEPROM_OVERRIDE_DIP_SW_DEFAULT 0 #define EEPROM_ENABLE_LEDS_DEFAULT 1 -#define EEPROM_ENABLE_SYNC_DEFAULT 1 #define EEPROM_ENABLE_STARTTIMER_DEFAULT 1 -#define EEPROM_SI5351_CALIBRATION_DEFAULT 0x00 -#define EEPROM_CLK0_OUT_DEFAULT 133000000 -#define EEPROM_CLK1_OUT_DEFAULT 70000000 -#define EEPROM_CLK2_OUT_DEFAULT 10700000 -#define EEPROM_CLK0_ONOFF_DEFAULT OFF -#define EEPROM_CLK1_ONOFF_DEFAULT OFF -#define EEPROM_CLK2_ONOFF_DEFAULT OFF - -#define EEPROM_BATTERY_EMPTY_MV 3430 - -/****************************************************** - * General definitions for making the code easier to understand */ -#define SDA_PIN (1 << PINC4) -#define SCL_PIN (1 << PINC5) -#define I2C_PINS (SCL_PIN | SDA_PIN) - #ifndef FALSE #define FALSE 0 #endif @@ -217,6 +200,7 @@ typedef enum #define MAX_TIME 4294967295L #define MAX_UINT16 65535 #define MAX_INT16 32767 +#define MIN_INT16 -32768 /* Periodic TIMER2 interrupt timing definitions */ #define TIMER2_57HZ 10 diff --git a/Arduino-microfox/linkbus.h b/Arduino-microfox/linkbus.h index abcc394..58df2bc 100644 --- a/Arduino-microfox/linkbus.h +++ b/Arduino-microfox/linkbus.h @@ -96,7 +96,6 @@ typedef enum MESSAGE_FACTORY_RESET = 'F' * 100 + 'A' * 10 + 'C', /* Sets EEPROM back to defaults */ MESSAGE_OVERRIDE_DIP = 'D' * 100 + 'I' * 10 + 'P', /* Override DIP switch settings using this value */ MESSAGE_LEDS = 'L' * 100 + 'E' * 10 + 'D', /* Turn on or off LEDs - accepts 1 or 0 or ON or OFF */ - MESSAGE_SYNC_ENABLE = 'S' * 100 + 'Y' * 10 + 'N', /* Enable or disable transmitter syncing */ MESSAGE_TEMP = 'T' * 100 + 'E' * 10 + 'M', /* Temperature data */ MESSAGE_SET_STATION_ID = 'I' * 10 + 'D', /* Sets amateur radio callsign text */ MESSAGE_GO = 'G' * 10 + 'O', /* Synchronizes clock */