From e91782ec658a08a5c3a07000a1f725d12ba0518f Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Tue, 14 Oct 2014 21:56:16 +0200 Subject: [PATCH] Autodetect SPI frequency - add statemachine for ISP sync & signature read - autoprobing of SPI frequency - remove manual SPI frequency selection - remove NVM code --- ispprog.c | 403 ++++++++++++++++++------------------------------------ 1 file changed, 134 insertions(+), 269 deletions(-) diff --git a/ispprog.c b/ispprog.c index 256ee66..cefcaba 100644 --- a/ispprog.c +++ b/ispprog.c @@ -19,11 +19,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include -#include #include #include #include -#include #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) @@ -114,21 +112,21 @@ #include #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1) -/* - * To select SPI SPEED press RESET_IN until LED starts blinking (about 5s) - * press RESET_IN to cycle through SPI speeds (LED frequency changes) - * after timout (about 5s) the LED turns off and the new SPI speed is set - */ - /* F_CPU /4 (1.8432MHz) */ #define SPI_MODE4 ((1< 0) { + /* try lower frequency */ + if (spi_speed > 0) { + spi_speed--; + } + + state = STATE_RESET_SYNC; + + } else { + /* got no sync, probe speed again next time */ + spi_speed = SPI_SPEED_PROBE; + state = STATE_IDLE; + } } break; - case STATE_SPEED2: + case STATE_RESET_PROGMODE: if (event == EV_STATE_ENTER) { - led_mode = LED_SPEED2; - timer = 500; /* timeout in 5s */ + + } else if (event == EV_PROG_LEAVE) { + /* was in prog mode (osc changed?), probe speed next time */ + spi_speed = SPI_SPEED_PROBE; + state = STATE_IDLE; } else if (event == EV_BUTTON_PRESSED) { - state = STATE_SPEED3; - - } else if (event == EV_TIMEOUT) { - state = STATE_NVRAM_STORE; - SPCR = SPI_MODE2; - } - break; - - case STATE_SPEED3: - if (event == EV_STATE_ENTER) { - led_mode = LED_SPEED3; - timer = 500; /* timeout in 5s */ - - } else if (event == EV_BUTTON_PRESSED) { - state = STATE_SPEED4; - - } else if (event == EV_TIMEOUT) { - state = STATE_NVRAM_STORE; - SPCR = SPI_MODE3; - } - break; - - case STATE_SPEED4: - if (event == EV_STATE_ENTER) { - led_mode = LED_SPEED4; - timer = 500; /* timeout in 5s */ - - } else if (event == EV_BUTTON_PRESSED) { - state = STATE_SPEED1; - - } else if (event == EV_TIMEOUT) { - state = STATE_NVRAM_STORE; - SPCR = SPI_MODE4; + state = STATE_IDLE; } break; @@ -1034,19 +909,16 @@ static uint16_t button_statemachine(uint8_t event) break; } - if (state == STATE_NVRAM_STORE) { - state = STATE_IDLE; - nvram_data.spi_mode = SPCR; - nvram_start_write(); - } + event = (oldstate != state) ? EV_STATE_ENTER + : EV_NONE; - if (event == EV_STATE_ENTER) { - oldstate = state; - } + } while (oldstate != state); - } while (state != oldstate); - - return timer; + cli(); + /* copy state back */ + reset_timer = timer; + reset_state = state; + sei(); } /* time keeping */ @@ -1071,22 +943,15 @@ ISR(TIMER0_OVF_vect) } } - static uint16_t timer; - if (timer) { - timer--; - if (timer == 0) { + if (reset_timer) { + reset_timer--; + if (reset_timer == 0) { event = EV_TIMEOUT; } } if (event != EV_NONE) { - uint16_t new_timer = button_statemachine(event); - if (new_timer == 0xFFFF) { - timer = 0; - - } else if (new_timer > 0) { - timer = new_timer; - } + reset_statemachine(event); } /* update LED */ @@ -1141,11 +1006,8 @@ int main(void) UCSR0C = (1<