diff options
Diffstat (limited to 'bootloaders/stk500v2/stk500boot.c')
-rw-r--r-- | bootloaders/stk500v2/stk500boot.c | 2122 |
1 files changed, 0 insertions, 2122 deletions
diff --git a/bootloaders/stk500v2/stk500boot.c b/bootloaders/stk500v2/stk500boot.c deleted file mode 100644 index 0b49dff..0000000 --- a/bootloaders/stk500v2/stk500boot.c +++ /dev/null @@ -1,2122 +0,0 @@ -/***************************************************************************** -Title: STK500v2 compatible bootloader - Modified for Wiring board ATMega128-16MHz -Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury -Compiler: avr-gcc 3.4.5 or 4.1 / avr-libc 1.4.3 -Hardware: All AVRs with bootloader support, tested with ATmega8 -License: GNU General Public License - -Modified: Worapoht Kornkaewwattanakul <dev@avride.com> http://www.avride.com -Date: 17 October 2007 -Update: 1st, 29 Dec 2007 : Enable CMD_SPI_MULTI but ignore unused command by return 0x00 byte response.. -Compiler: WINAVR20060421 -Description: add timeout feature like previous Wiring bootloader - -DESCRIPTION: - This program allows an AVR with bootloader capabilities to - read/write its own Flash/EEprom. To enter Programming mode - an input pin is checked. If this pin is pulled low, programming mode - is entered. If not, normal execution is done from $0000 - "reset" vector in Application area. - Size fits into a 1024 word bootloader section - when compiled with avr-gcc 4.1 - (direct replace on Wiring Board without fuse setting changed) - -USAGE: - - Set AVR MCU type and clock-frequency (F_CPU) in the Makefile. - - Set baud rate below (AVRISP only works with 115200 bps) - - compile/link the bootloader with the supplied Makefile - - program the "Boot Flash section size" (BOOTSZ fuses), - for boot-size 1024 words: program BOOTSZ01 - - enable the BOOT Reset Vector (program BOOTRST) - - Upload the hex file to the AVR using any ISP programmer - - Program Boot Lock Mode 3 (program BootLock 11 and BootLock 12 lock bits) // (leave them) - - Reset your AVR while keeping PROG_PIN pulled low // (for enter bootloader by switch) - - Start AVRISP Programmer (AVRStudio/Tools/Program AVR) - - AVRISP will detect the bootloader - - Program your application FLASH file and optional EEPROM file using AVRISP - -Note: - Erasing the device without flashing, through AVRISP GUI button "Erase Device" - is not implemented, due to AVRStudio limitations. - Flash is always erased before programming. - - AVRdude: - Please uncomment #define REMOVE_CMD_SPI_MULTI when using AVRdude. - Comment #define REMOVE_PROGRAM_LOCK_BIT_SUPPORT to reduce code size - Read Fuse Bits and Read/Write Lock Bits is not supported - -NOTES: - Based on Atmel Application Note AVR109 - Self-programming - Based on Atmel Application Note AVR068 - STK500v2 Protocol - -LICENSE: - Copyright (C) 2006 Peter Fleury - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*****************************************************************************/ - -//************************************************************************ -//* Edit History -//************************************************************************ -//* Jul 7, 2010 <MLS> = Mark Sproul msproul@skycharoit.com -//* Jul 7, 2010 <MLS> Working on mega2560. No Auto-restart -//* Jul 7, 2010 <MLS> Switched to 8K bytes (4K words) so that we have room for the monitor -//* Jul 8, 2010 <MLS> Found older version of source that had auto restart, put that code back in -//* Jul 8, 2010 <MLS> Adding monitor code -//* Jul 11, 2010 <MLS> Added blinking LED while waiting for download to start -//* Jul 11, 2010 <MLS> Added EEPROM test -//* Jul 29, 2010 <MLS> Added recchar_timeout for timing out on bootloading -//* Aug 23, 2010 <MLS> Added support for atmega2561 -//* Aug 26, 2010 <MLS> Removed support for BOOT_BY_SWITCH -//* Sep 8, 2010 <MLS> Added support for atmega16 -//* Nov 9, 2010 <MLS> Issue 392:Fixed bug that 3 !!! in code would cause it to jump to monitor -//* Jun 24, 2011 <MLS> Removed analogRead (was not used) -//* Dec 29, 2011 <MLS> Issue 181: added watch dog timmer support -//* Dec 29, 2011 <MLS> Issue 505: bootloader is comparing the seqNum to 1 or the current sequence -//* Jan 1, 2012 <MLS> Issue 543: CMD_CHIP_ERASE_ISP now returns STATUS_CMD_FAILED instead of STATUS_CMD_OK -//* Jan 1, 2012 <MLS> Issue 543: Write EEPROM now does something (NOT TESTED) -//* Jan 1, 2012 <MLS> Issue 544: stk500v2 bootloader doesn't support reading fuses -//************************************************************************ - -//************************************************************************ -//* these are used to test issues -//* http://code.google.com/p/arduino/issues/detail?id=505 -//* Reported by mark.stubbs, Mar 14, 2011 -//* The STK500V2 bootloader is comparing the seqNum to 1 or the current sequence -//* (IE: Requiring the sequence to be 1 or match seqNum before continuing). -//* The correct behavior is for the STK500V2 to accept the PC's sequence number, and echo it back for the reply message. -#define _FIX_ISSUE_505_ -//************************************************************************ -//* Issue 181: added watch dog timmer support -#define _FIX_ISSUE_181_ - -#include <inttypes.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include <avr/boot.h> -#include <avr/pgmspace.h> -#include <util/delay.h> -#include <avr/eeprom.h> -#include <avr/common.h> -#include <stdlib.h> -#include "command.h" - - -#if defined(_MEGA_BOARD_) || defined(_BOARD_AMBER128_) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \ - || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1284P__) || defined(ENABLE_MONITOR) - #undef ENABLE_MONITOR - #define ENABLE_MONITOR - static void RunMonitor(void); -#endif - -#ifndef EEWE - #define EEWE 1 -#endif -#ifndef EEMWE - #define EEMWE 2 -#endif - -//#define _DEBUG_SERIAL_ -//#define _DEBUG_WITH_LEDS_ - - -/* - * Uncomment the following lines to save code space - */ -//#define REMOVE_PROGRAM_LOCK_BIT_SUPPORT // disable program lock bits -//#define REMOVE_BOOTLOADER_LED // no LED to show active bootloader -//#define REMOVE_CMD_SPI_MULTI // disable processing of SPI_MULTI commands, Remark this line for AVRDUDE <Worapoht> -// - - - -//************************************************************************ -//* LED on pin "PROGLED_PIN" on port "PROGLED_PORT" -//* indicates that bootloader is active -//* PG2 -> LED on Wiring board -//************************************************************************ -#define BLINK_LED_WHILE_WAITING - -#ifdef _MEGA_BOARD_ - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB7 -#elif defined( _BOARD_AMBER128_ ) - //* this is for the amber 128 http://www.soc-robotics.com/ - //* onbarod led is PORTE4 - #define PROGLED_PORT PORTD - #define PROGLED_DDR DDRD - #define PROGLED_PIN PINE7 -#elif defined( _CEREBOTPLUS_BOARD_ ) || defined(_CEREBOT_II_BOARD_) - //* this is for the Cerebot 2560 board and the Cerebot-ii - //* onbarod leds are on PORTE4-7 - #define PROGLED_PORT PORTE - #define PROGLED_DDR DDRE - #define PROGLED_PIN PINE7 -#elif defined( _PENGUINO_ ) - //* this is for the Penguino - //* onbarod led is PORTE4 - #define PROGLED_PORT PORTC - #define PROGLED_DDR DDRC - #define PROGLED_PIN PINC6 -#elif defined( _ANDROID_2561_ ) || defined( __AVR_ATmega2561__ ) - //* this is for the Boston Android 2561 - //* onbarod led is PORTE4 - #define PROGLED_PORT PORTA - #define PROGLED_DDR DDRA - #define PROGLED_PIN PINA3 -#elif defined( _BOARD_MEGA16 ) - //* onbarod led is PORTA7 - #define PROGLED_PORT PORTA - #define PROGLED_DDR DDRA - #define PROGLED_PIN PINA7 - #define UART_BAUDRATE_DOUBLE_SPEED 0 - -#elif defined( _BOARD_BAHBOT_ ) - //* dosent have an onboard LED but this is what will probably be added to this port - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB0 - -#elif defined( _BOARD_ROBOTX_ ) - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB6 -#elif defined( _BOARD_CUSTOM1284_BLINK_B0_ ) - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB0 -#elif defined( _BOARD_CUSTOM1284_ ) - #define PROGLED_PORT PORTD - #define PROGLED_DDR DDRD - #define PROGLED_PIN PIND5 -#elif defined( _AVRLIP_ ) - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB5 -#elif defined( _BOARD_STK500_ ) - #define PROGLED_PORT PORTA - #define PROGLED_DDR DDRA - #define PROGLED_PIN PINA7 -#elif defined( _BOARD_STK502_ ) - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB5 -#elif defined( _BOARD_STK525_ ) - #define PROGLED_PORT PORTB - #define PROGLED_DDR DDRB - #define PROGLED_PIN PINB7 -#else - #define PROGLED_PORT PORTG - #define PROGLED_DDR DDRG - #define PROGLED_PIN PING2 -#endif - - - -/* - * define CPU frequency in Mhz here if not defined in Makefile - */ -#ifndef F_CPU - #define F_CPU 16000000UL -#endif - -#define _BLINK_LOOP_COUNT_ (F_CPU / 2250) -/* - * UART Baudrate, AVRStudio AVRISP only accepts 115200 bps - */ - -#ifndef BAUDRATE - #define BAUDRATE 115200 -#endif - -/* - * Enable (1) or disable (0) USART double speed operation - */ -#ifndef UART_BAUDRATE_DOUBLE_SPEED - #if defined (__AVR_ATmega32__) - #define UART_BAUDRATE_DOUBLE_SPEED 0 - #else - #define UART_BAUDRATE_DOUBLE_SPEED 1 - #endif -#endif - -/* - * HW and SW version, reported to AVRISP, must match version of AVRStudio - */ -#define CONFIG_PARAM_BUILD_NUMBER_LOW 0 -#define CONFIG_PARAM_BUILD_NUMBER_HIGH 0 -#define CONFIG_PARAM_HW_VER 0x0F -#define CONFIG_PARAM_SW_MAJOR 2 -#define CONFIG_PARAM_SW_MINOR 0x0A - -/* - * Calculate the address where the bootloader starts from FLASHEND and BOOTSIZE - * (adjust BOOTSIZE below and BOOTLOADER_ADDRESS in Makefile if you want to change the size of the bootloader) - */ -//#define BOOTSIZE 1024 -#if FLASHEND > 0x0F000 - #define BOOTSIZE 8192 -#else - #define BOOTSIZE 2048 -#endif - -#define APP_END (FLASHEND -(2*BOOTSIZE) + 1) - -/* - * Signature bytes are not available in avr-gcc io_xxx.h - */ -#if defined (__AVR_ATmega8__) - #define SIGNATURE_BYTES 0x1E9307 -#elif defined (__AVR_ATmega16__) - #define SIGNATURE_BYTES 0x1E9403 -#elif defined (__AVR_ATmega32__) - #define SIGNATURE_BYTES 0x1E9502 -#elif defined (__AVR_ATmega8515__) - #define SIGNATURE_BYTES 0x1E9306 -#elif defined (__AVR_ATmega8535__) - #define SIGNATURE_BYTES 0x1E9308 -#elif defined (__AVR_ATmega162__) - #define SIGNATURE_BYTES 0x1E9404 -#elif defined (__AVR_ATmega128__) - #define SIGNATURE_BYTES 0x1E9702 -#elif defined (__AVR_ATmega1280__) - #define SIGNATURE_BYTES 0x1E9703 -#elif defined (__AVR_ATmega2560__) - #define SIGNATURE_BYTES 0x1E9801 -#elif defined (__AVR_ATmega2561__) - #define SIGNATURE_BYTES 0x1e9802 -#elif defined (__AVR_ATmega1284P__) - #define SIGNATURE_BYTES 0x1e9705 -#elif defined (__AVR_ATmega640__) - #define SIGNATURE_BYTES 0x1e9608 -#elif defined (__AVR_ATmega64__) - #define SIGNATURE_BYTES 0x1E9602 -#elif defined (__AVR_ATmega169__) - #define SIGNATURE_BYTES 0x1e9405 -#elif defined (__AVR_AT90USB1287__) - #define SIGNATURE_BYTES 0x1e9782 -#else - #error "no signature definition for MCU available" -#endif - - -#if defined(_BOARD_ROBOTX_) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) - #define UART_BAUD_RATE_LOW UBRR1L - #define UART_STATUS_REG UCSR1A - #define UART_CONTROL_REG UCSR1B - #define UART_ENABLE_TRANSMITTER TXEN1 - #define UART_ENABLE_RECEIVER RXEN1 - #define UART_TRANSMIT_COMPLETE TXC1 - #define UART_RECEIVE_COMPLETE RXC1 - #define UART_DATA_REG UDR1 - #define UART_DOUBLE_SPEED U2X1 - -#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ - || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) - /* ATMega8 with one USART */ - #define UART_BAUD_RATE_LOW UBRRL - #define UART_STATUS_REG UCSRA - #define UART_CONTROL_REG UCSRB - #define UART_ENABLE_TRANSMITTER TXEN - #define UART_ENABLE_RECEIVER RXEN - #define UART_TRANSMIT_COMPLETE TXC - #define UART_RECEIVE_COMPLETE RXC - #define UART_DATA_REG UDR - #define UART_DOUBLE_SPEED U2X - -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega162__) \ - || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) - /* ATMega with two USART, use UART0 */ - #define UART_BAUD_RATE_LOW UBRR0L - #define UART_STATUS_REG UCSR0A - #define UART_CONTROL_REG UCSR0B - #define UART_ENABLE_TRANSMITTER TXEN0 - #define UART_ENABLE_RECEIVER RXEN0 - #define UART_TRANSMIT_COMPLETE TXC0 - #define UART_RECEIVE_COMPLETE RXC0 - #define UART_DATA_REG UDR0 - #define UART_DOUBLE_SPEED U2X0 -#elif defined(UBRR0L) && defined(UCSR0A) && defined(TXEN0) - /* ATMega with two USART, use UART0 */ - #define UART_BAUD_RATE_LOW UBRR0L - #define UART_STATUS_REG UCSR0A - #define UART_CONTROL_REG UCSR0B - #define UART_ENABLE_TRANSMITTER TXEN0 - #define UART_ENABLE_RECEIVER RXEN0 - #define UART_TRANSMIT_COMPLETE TXC0 - #define UART_RECEIVE_COMPLETE RXC0 - #define UART_DATA_REG UDR0 - #define UART_DOUBLE_SPEED U2X0 -#elif defined(UBRRL) && defined(UCSRA) && defined(UCSRB) && defined(TXEN) && defined(RXEN) - //* catch all - #define UART_BAUD_RATE_LOW UBRRL - #define UART_STATUS_REG UCSRA - #define UART_CONTROL_REG UCSRB - #define UART_ENABLE_TRANSMITTER TXEN - #define UART_ENABLE_RECEIVER RXEN - #define UART_TRANSMIT_COMPLETE TXC - #define UART_RECEIVE_COMPLETE RXC - #define UART_DATA_REG UDR - #define UART_DOUBLE_SPEED U2X -#else - #error "no UART definition for MCU available" -#endif - - - -/* - * Macro to calculate UBBR from XTAL and baudrate - */ -#if defined(__AVR_ATmega32__) && UART_BAUDRATE_DOUBLE_SPEED - #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu / 4 / baudRate - 1) / 2) -#elif defined(__AVR_ATmega32__) - #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu / 8 / baudRate - 1) / 2) -#elif UART_BAUDRATE_DOUBLE_SPEED - #define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*8.0)-1.0+0.5) -#else - #define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*16.0)-1.0+0.5) -#endif - - -/* - * States used in the receive state machine - */ -#define ST_START 0 -#define ST_GET_SEQ_NUM 1 -#define ST_MSG_SIZE_1 2 -#define ST_MSG_SIZE_2 3 -#define ST_GET_TOKEN 4 -#define ST_GET_DATA 5 -#define ST_GET_CHECK 6 -#define ST_PROCESS 7 - -/* - * use 16bit address variable for ATmegas with <= 64K flash - */ -#if defined(RAMPZ) - typedef uint32_t address_t; -#else - typedef uint16_t address_t; -#endif - -/* - * function prototypes - */ -static void sendchar(char c); -static unsigned char recchar(void); - -/* - * since this bootloader is not linked against the avr-gcc crt1 functions, - * to reduce the code size, we need to provide our own initialization - */ -void __jumpMain (void) __attribute__ ((naked)) __attribute__ ((section (".init9"))); -#include <avr/sfr_defs.h> - -//#define SPH_REG 0x3E -//#define SPL_REG 0x3D - -//***************************************************************************** -void __jumpMain(void) -{ -//* July 17, 2010 <MLS> Added stack pointer initialzation -//* the first line did not do the job on the ATmega128 - - asm volatile ( ".set __stack, %0" :: "i" (RAMEND) ); - -//* set stack pointer to top of RAM - - asm volatile ( "ldi 16, %0" :: "i" (RAMEND >> 8) ); - asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_HI_ADDR) ); - - asm volatile ( "ldi 16, %0" :: "i" (RAMEND & 0x0ff) ); - asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_LO_ADDR) ); - - asm volatile ( "clr __zero_reg__" ); // GCC depends on register r1 set to 0 - asm volatile ( "out %0, __zero_reg__" :: "I" (_SFR_IO_ADDR(SREG)) ); // set SREG to 0 - asm volatile ( "jmp main"); // jump to main() -} - - -//***************************************************************************** -void delay_ms(unsigned int timedelay) -{ - unsigned int i; - for (i=0;i<timedelay;i++) - { - _delay_ms(0.5); - } -} - - -//***************************************************************************** -/* - * send single byte to USART, wait until transmission is completed - */ -static void sendchar(char c) -{ - UART_DATA_REG = c; // prepare transmission - while (!(UART_STATUS_REG & (1 << UART_TRANSMIT_COMPLETE))); // wait until byte sent - UART_STATUS_REG |= (1 << UART_TRANSMIT_COMPLETE); // delete TXCflag -} - - -//************************************************************************ -static int Serial_Available(void) -{ - return(UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE)); // wait for data -} - - -//***************************************************************************** -/* - * Read single byte from USART, block if no data available - */ -static unsigned char recchar(void) -{ - while (!(UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE))) - { - // wait for data - } - return UART_DATA_REG; -} - -#define MAX_TIME_COUNT (F_CPU >> 1) -//***************************************************************************** -static unsigned char recchar_timeout(void) -{ -uint32_t count = 0; - - while (!(UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE))) - { - // wait for data - count++; - if (count > MAX_TIME_COUNT) - { - unsigned int data; - #if (FLASHEND > 0x10000) - data = pgm_read_word_far(0); //* get the first word of the user program - #else - data = pgm_read_word_near(0); //* get the first word of the user program - #endif - if (data != 0xffff) //* make sure its valid before jumping to it. - { - asm volatile( - "clr r30 \n\t" - "clr r31 \n\t" - "ijmp \n\t" - ); - } - count = 0; - } - } - return UART_DATA_REG; -} - -//* for watch dog timer startup -void (*app_start)(void) = 0x0000; - - -//***************************************************************************** -int main(void) -{ - address_t address = 0; - address_t eraseAddress = 0; - unsigned char msgParseState; - unsigned int ii = 0; - unsigned char checksum = 0; - unsigned char seqNum = 0; - unsigned int msgLength = 0; - unsigned char msgBuffer[285]; - unsigned char c, *p; - unsigned char isLeave = 0; - - unsigned long boot_timeout; - unsigned long boot_timer; - unsigned int boot_state; -#ifdef ENABLE_MONITOR - unsigned int exPointCntr = 0; - unsigned int rcvdCharCntr = 0; -#endif - - //* some chips dont set the stack properly - asm volatile ( ".set __stack, %0" :: "i" (RAMEND) ); - asm volatile ( "ldi 16, %0" :: "i" (RAMEND >> 8) ); - asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_HI_ADDR) ); - asm volatile ( "ldi 16, %0" :: "i" (RAMEND & 0x0ff) ); - asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_LO_ADDR) ); - -#ifdef _FIX_ISSUE_181_ - //************************************************************************ - //* Dec 29, 2011 <MLS> Issue #181, added watch dog timmer support - //* handle the watch dog timer - uint8_t mcuStatusReg; - mcuStatusReg = MCUSR; - - __asm__ __volatile__ ("cli"); - __asm__ __volatile__ ("wdr"); - MCUSR = 0; - WDTCSR |= _BV(WDCE) | _BV(WDE); - WDTCSR = 0; - __asm__ __volatile__ ("sei"); - // check if WDT generated the reset, if so, go straight to app - if (mcuStatusReg & _BV(WDRF)) - { - app_start(); - } - //************************************************************************ -#endif - - - boot_timer = 0; - boot_state = 0; - -#ifdef BLINK_LED_WHILE_WAITING -// boot_timeout = 90000; //* should be about 4 seconds -// boot_timeout = 170000; - boot_timeout = 20000; //* should be about 1 second -#else - boot_timeout = 3500000; // 7 seconds , approx 2us per step when optimize "s" -#endif - /* - * Branch to bootloader or application code ? - */ - -#ifndef REMOVE_BOOTLOADER_LED - /* PROG_PIN pulled low, indicate with LED that bootloader is active */ - PROGLED_DDR |= (1<<PROGLED_PIN); -// PROGLED_PORT &= ~(1<<PROGLED_PIN); // active low LED ON - PROGLED_PORT |= (1<<PROGLED_PIN); // active high LED ON - -#ifdef _DEBUG_WITH_LEDS_ - for (ii=0; ii<3; ii++) - { - PROGLED_PORT &= ~(1<<PROGLED_PIN); // turn LED off - delay_ms(100); - PROGLED_PORT |= (1<<PROGLED_PIN); // turn LED on - delay_ms(100); - } -#endif - -#endif - /* - * Init UART - * set baudrate and enable USART receiver and transmiter without interrupts - */ -#if UART_BAUDRATE_DOUBLE_SPEED - UART_STATUS_REG |= (1 <<UART_DOUBLE_SPEED); -#endif - UART_BAUD_RATE_LOW = UART_BAUD_SELECT(BAUDRATE,F_CPU); - UART_CONTROL_REG = (1 << UART_ENABLE_RECEIVER) | (1 << UART_ENABLE_TRANSMITTER); - - asm volatile ("nop"); // wait until port has changed - -#ifdef _DEBUG_SERIAL_ -// delay_ms(500); - - sendchar('s'); - sendchar('t'); - sendchar('k'); -// sendchar('5'); -// sendchar('0'); -// sendchar('0'); - sendchar('v'); - sendchar('2'); - sendchar(0x0d); - sendchar(0x0a); - - delay_ms(100); -#endif - - while (boot_state==0) - { - while ((!(Serial_Available())) && (boot_state == 0)) // wait for data - { - _delay_ms(0.001); - boot_timer++; - if (boot_timer > boot_timeout) - { - boot_state = 1; // (after ++ -> boot_state=2 bootloader timeout, jump to main 0x00000 ) - } - #ifdef BLINK_LED_WHILE_WAITING - if ((boot_timer % _BLINK_LOOP_COUNT_) == 0) - { - //* toggle the LED - PROGLED_PORT ^= (1<<PROGLED_PIN); // turn LED ON - } - #endif - } - boot_state++; // ( if boot_state=1 bootloader received byte from UART, enter bootloader mode) - } - - - if (boot_state==1) - { - //* main loop - while (!isLeave) - { - /* - * Collect received bytes to a complete message - */ - msgParseState = ST_START; - while ( msgParseState != ST_PROCESS ) - { - if (boot_state==1) - { - boot_state = 0; - c = UART_DATA_REG; - } - else - { - // c = recchar(); - c = recchar_timeout(); - - } - - #ifdef ENABLE_MONITOR - rcvdCharCntr++; - - if ((c == '!') && (rcvdCharCntr < 10)) - { - exPointCntr++; - if (exPointCntr == 3) - { - RunMonitor(); - exPointCntr = 0; // reset back to zero so we dont get in an endless loop - isLeave = 1; - msgParseState = 99; //* we dont want it do anything - break; - } - } - else - { - exPointCntr = 0; - } - #endif - - switch (msgParseState) - { - case ST_START: - if ( c == MESSAGE_START ) - { - msgParseState = ST_GET_SEQ_NUM; - checksum = MESSAGE_START^0; - } - break; - - case ST_GET_SEQ_NUM: - #ifdef _FIX_ISSUE_505_ - seqNum = c; - msgParseState = ST_MSG_SIZE_1; - checksum ^= c; - #else - if ( (c == 1) || (c == seqNum) ) - { - seqNum = c; - msgParseState = ST_MSG_SIZE_1; - checksum ^= c; - } - else - { - msgParseState = ST_START; - } - #endif - break; - - case ST_MSG_SIZE_1: - msgLength = c<<8; - msgParseState = ST_MSG_SIZE_2; - checksum ^= c; - break; - - case ST_MSG_SIZE_2: - msgLength |= c; - msgParseState = ST_GET_TOKEN; - checksum ^= c; - break; - - case ST_GET_TOKEN: - if ( c == TOKEN ) - { - msgParseState = ST_GET_DATA; - checksum ^= c; - ii = 0; - } - else - { - msgParseState = ST_START; - } - break; - - case ST_GET_DATA: - msgBuffer[ii++] = c; - checksum ^= c; - if (ii == msgLength ) - { - msgParseState = ST_GET_CHECK; - } - break; - - case ST_GET_CHECK: - if ( c == checksum ) - { - msgParseState = ST_PROCESS; - } - else - { - msgParseState = ST_START; - } - break; - } // switch - } // while(msgParseState) - - /* - * Now process the STK500 commands, see Atmel Appnote AVR068 - */ - - switch (msgBuffer[0]) - { - #ifndef REMOVE_CMD_SPI_MULTI - case CMD_SPI_MULTI: - { - unsigned char answerByte; - unsigned char flag=0; - - if ( msgBuffer[4]== 0x30 ) - { - unsigned char signatureIndex = msgBuffer[6]; - - if ( signatureIndex == 0 ) - { - answerByte = (SIGNATURE_BYTES >> 16) & 0x000000FF; - } - else if ( signatureIndex == 1 ) - { - answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF; - } - else - { - answerByte = SIGNATURE_BYTES & 0x000000FF; - } - } - else if ( msgBuffer[4] & 0x50 ) - { - //* Issue 544: stk500v2 bootloader doesn't support reading fuses - //* I cant find the docs that say what these are supposed to be but this was figured out by trial and error - // answerByte = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); - // answerByte = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - // answerByte = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); - if (msgBuffer[4] == 0x50) - { - answerByte = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); - } - else if (msgBuffer[4] == 0x58) - { - answerByte = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - } - else - { - answerByte = 0; - } - } - else - { - answerByte = 0; // for all others command are not implemented, return dummy value for AVRDUDE happy <Worapoht> - } - if ( !flag ) - { - msgLength = 7; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = 0; - msgBuffer[3] = msgBuffer[4]; - msgBuffer[4] = 0; - msgBuffer[5] = answerByte; - msgBuffer[6] = STATUS_CMD_OK; - } - } - break; - #endif - case CMD_SIGN_ON: - msgLength = 11; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = 8; - msgBuffer[3] = 'A'; - msgBuffer[4] = 'V'; - msgBuffer[5] = 'R'; - msgBuffer[6] = 'I'; - msgBuffer[7] = 'S'; - msgBuffer[8] = 'P'; - msgBuffer[9] = '_'; - msgBuffer[10] = '2'; - break; - - case CMD_GET_PARAMETER: - { - unsigned char value; - - switch(msgBuffer[1]) - { - case PARAM_BUILD_NUMBER_LOW: - value = CONFIG_PARAM_BUILD_NUMBER_LOW; - break; - case PARAM_BUILD_NUMBER_HIGH: - value = CONFIG_PARAM_BUILD_NUMBER_HIGH; - break; - case PARAM_HW_VER: - value = CONFIG_PARAM_HW_VER; - break; - case PARAM_SW_MAJOR: - value = CONFIG_PARAM_SW_MAJOR; - break; - case PARAM_SW_MINOR: - value = CONFIG_PARAM_SW_MINOR; - break; - default: - value = 0; - break; - } - msgLength = 3; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = value; - } - break; - - case CMD_LEAVE_PROGMODE_ISP: - isLeave = 1; - //* fall thru - - case CMD_SET_PARAMETER: - case CMD_ENTER_PROGMODE_ISP: - msgLength = 2; - msgBuffer[1] = STATUS_CMD_OK; - break; - - case CMD_READ_SIGNATURE_ISP: - { - unsigned char signatureIndex = msgBuffer[4]; - unsigned char signature; - - if ( signatureIndex == 0 ) - signature = (SIGNATURE_BYTES >>16) & 0x000000FF; - else if ( signatureIndex == 1 ) - signature = (SIGNATURE_BYTES >> 8) & 0x000000FF; - else - signature = SIGNATURE_BYTES & 0x000000FF; - - msgLength = 4; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = signature; - msgBuffer[3] = STATUS_CMD_OK; - } - break; - - case CMD_READ_LOCK_ISP: - msgLength = 4; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = boot_lock_fuse_bits_get( GET_LOCK_BITS ); - msgBuffer[3] = STATUS_CMD_OK; - break; - - case CMD_READ_FUSE_ISP: - { - unsigned char fuseBits; - - if ( msgBuffer[2] == 0x50 ) - { - if ( msgBuffer[3] == 0x08 ) - fuseBits = boot_lock_fuse_bits_get( GET_EXTENDED_FUSE_BITS ); - else - fuseBits = boot_lock_fuse_bits_get( GET_LOW_FUSE_BITS ); - } - else - { - fuseBits = boot_lock_fuse_bits_get( GET_HIGH_FUSE_BITS ); - } - msgLength = 4; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = fuseBits; - msgBuffer[3] = STATUS_CMD_OK; - } - break; - - #ifndef REMOVE_PROGRAM_LOCK_BIT_SUPPORT - case CMD_PROGRAM_LOCK_ISP: - { - unsigned char lockBits = msgBuffer[4]; - - lockBits = (~lockBits) & 0x3C; // mask BLBxx bits - boot_lock_bits_set(lockBits); // and program it - boot_spm_busy_wait(); - - msgLength = 3; - msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[2] = STATUS_CMD_OK; - } - break; - #endif - case CMD_CHIP_ERASE_ISP: - eraseAddress = 0; - msgLength = 2; - // msgBuffer[1] = STATUS_CMD_OK; - msgBuffer[1] = STATUS_CMD_FAILED; //* isue 543, return FAILED instead of OK - break; - - case CMD_LOAD_ADDRESS: - #if defined(RAMPZ) - address = ( ((address_t)(msgBuffer[1])<<24)|((address_t)(msgBuffer[2])<<16)|((address_t)(msgBuffer[3])<<8)|(msgBuffer[4]) )<<1; - #else - address = ( ((msgBuffer[3])<<8)|(msgBuffer[4]) )<<1; //convert word to byte address - #endif - msgLength = 2; - msgBuffer[1] = STATUS_CMD_OK; - break; - - case CMD_PROGRAM_FLASH_ISP: - case CMD_PROGRAM_EEPROM_ISP: - { - unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2]; - unsigned char *p = msgBuffer+10; - unsigned int data; - unsigned char highByte, lowByte; - address_t tempaddress = address; - - - if ( msgBuffer[0] == CMD_PROGRAM_FLASH_ISP ) - { - // erase only main section (bootloader protection) - if (eraseAddress < APP_END ) - { - boot_page_erase(eraseAddress); // Perform page erase - boot_spm_busy_wait(); // Wait until the memory is erased. - eraseAddress += SPM_PAGESIZE; // point to next page to be erase - } - - /* Write FLASH */ - do { - lowByte = *p++; - highByte = *p++; - - data = (highByte << 8) | lowByte; - boot_page_fill(address,data); - - address = address + 2; // Select next word in memory - size -= 2; // Reduce number of bytes to write by two - } while (size); // Loop until all bytes written - - boot_page_write(tempaddress); - boot_spm_busy_wait(); - boot_rww_enable(); // Re-enable the RWW section - } - else - { - //* issue 543, this should work, It has not been tested. - uint16_t ii = address >> 1; - /* write EEPROM */ - while (size) { - eeprom_write_byte((uint8_t*)ii, *p++); - address+=2; // Select next EEPROM byte - ii++; - size--; - } - } - msgLength = 2; - msgBuffer[1] = STATUS_CMD_OK; - } - break; - - case CMD_READ_FLASH_ISP: - case CMD_READ_EEPROM_ISP: - { - unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2]; - unsigned char *p = msgBuffer+1; - msgLength = size+3; - - *p++ = STATUS_CMD_OK; - if (msgBuffer[0] == CMD_READ_FLASH_ISP ) - { - unsigned int data; - - // Read FLASH - do { - //#if defined(RAMPZ) - #if (FLASHEND > 0x10000) - data = pgm_read_word_far(address); - #else - data = pgm_read_word_near(address); - #endif - *p++ = (unsigned char)data; //LSB - *p++ = (unsigned char)(data >> 8); //MSB - address += 2; // Select next word in memory - size -= 2; - }while (size); - } - else - { - /* Read EEPROM */ - do { - EEARL = address; // Setup EEPROM address - EEARH = ((address >> 8)); - address++; // Select next EEPROM byte - EECR |= (1<<EERE); // Read EEPROM - *p++ = EEDR; // Send EEPROM data - size--; - } while (size); - } - *p++ = STATUS_CMD_OK; - } - break; - - default: - msgLength = 2; - msgBuffer[1] = STATUS_CMD_FAILED; - break; - } - - /* - * Now send answer message back - */ - sendchar(MESSAGE_START); - checksum = MESSAGE_START^0; - - sendchar(seqNum); - checksum ^= seqNum; - - c = ((msgLength>>8)&0xFF); - sendchar(c); - checksum ^= c; - - c = msgLength&0x00FF; - sendchar(c); - checksum ^= c; - - sendchar(TOKEN); - checksum ^= TOKEN; - - p = msgBuffer; - while ( msgLength ) - { - c = *p++; - sendchar(c); - checksum ^=c; - msgLength--; - } - sendchar(checksum); - seqNum++; - - #ifndef REMOVE_BOOTLOADER_LED - //* <MLS> toggle the LED - PROGLED_PORT ^= (1<<PROGLED_PIN); // active high LED ON - #endif - - } - } - -#ifdef _DEBUG_WITH_LEDS_ - //* this is for debugging it can be removed - for (ii=0; ii<10; ii++) - { - PROGLED_PORT &= ~(1<<PROGLED_PIN); // turn LED off - delay_ms(200); - PROGLED_PORT |= (1<<PROGLED_PIN); // turn LED on - delay_ms(200); - } - PROGLED_PORT &= ~(1<<PROGLED_PIN); // turn LED off -#endif - -#ifdef _DEBUG_SERIAL_ - sendchar('j'); -// sendchar('u'); -// sendchar('m'); -// sendchar('p'); -// sendchar(' '); -// sendchar('u'); -// sendchar('s'); -// sendchar('r'); - sendchar(0x0d); - sendchar(0x0a); - - delay_ms(100); -#endif - - -#ifndef REMOVE_BOOTLOADER_LED - PROGLED_DDR &= ~(1<<PROGLED_PIN); // set to default - PROGLED_PORT &= ~(1<<PROGLED_PIN); // active low LED OFF -// PROGLED_PORT |= (1<<PROGLED_PIN); // active high LED OFf - delay_ms(100); // delay after exit -#endif - - - asm volatile ("nop"); // wait until port has changed - - /* - * Now leave bootloader - */ - - UART_STATUS_REG &= 0xfd; - boot_rww_enable(); // enable application section - - - asm volatile( - "clr r30 \n\t" - "clr r31 \n\t" - "ijmp \n\t" - ); -// asm volatile ( "push r1" "\n\t" // Jump to Reset vector in Application Section -// "push r1" "\n\t" -// "ret" "\n\t" -// ::); - - /* - * Never return to stop GCC to generate exit return code - * Actually we will never reach this point, but the compiler doesn't - * understand this - */ - for(;;); -} - -/* -base address = f800 - -avrdude: Device signature = 0x1e9703 -avrdude: safemode: lfuse reads as FF -avrdude: safemode: hfuse reads as DA -avrdude: safemode: efuse reads as F5 -avrdude> - - -base address = f000 -avrdude: Device signature = 0x1e9703 -avrdude: safemode: lfuse reads as FF -avrdude: safemode: hfuse reads as D8 -avrdude: safemode: efuse reads as F5 -avrdude> -*/ - -//************************************************************************ -#ifdef ENABLE_MONITOR -#include <math.h> - -unsigned long gRamIndex; -unsigned long gFlashIndex; -unsigned long gEepromIndex; - - -#define true 1 -#define false 0 - -#include "avr_cpunames.h" - -#ifndef _AVR_CPU_NAME_ - #error cpu name not defined -#endif - -#ifdef _VECTORS_SIZE - #define kInterruptVectorCount (_VECTORS_SIZE / 4) -#else - #define kInterruptVectorCount 23 -#endif - - -void PrintDecInt(int theNumber, int digitCnt); - -#ifdef _AVR_CPU_NAME_ - const char gTextMsg_CPU_Name[] PROGMEM = _AVR_CPU_NAME_; -#else - const char gTextMsg_CPU_Name[] PROGMEM = "UNKNOWN"; -#endif - - const char gTextMsg_Explorer[] PROGMEM = "Arduino explorer stk500V2 by MLS"; - const char gTextMsg_Prompt[] PROGMEM = "Bootloader>"; - const char gTextMsg_HUH[] PROGMEM = "Huh?"; - const char gTextMsg_COMPILED_ON[] PROGMEM = "Compiled on = "; - const char gTextMsg_CPU_Type[] PROGMEM = "CPU Type = "; - const char gTextMsg_AVR_ARCH[] PROGMEM = "__AVR_ARCH__= "; - const char gTextMsg_AVR_LIBC[] PROGMEM = "AVR LibC Ver= "; - const char gTextMsg_GCC_VERSION[] PROGMEM = "GCC Version = "; - const char gTextMsg_CPU_SIGNATURE[] PROGMEM = "CPU ID = "; - const char gTextMsg_FUSE_BYTE_LOW[] PROGMEM = "Low fuse = "; - const char gTextMsg_FUSE_BYTE_HIGH[] PROGMEM = "High fuse = "; - const char gTextMsg_FUSE_BYTE_EXT[] PROGMEM = "Ext fuse = "; - const char gTextMsg_FUSE_BYTE_LOCK[] PROGMEM = "Lock fuse = "; - const char gTextMsg_GCC_DATE_STR[] PROGMEM = __DATE__; - const char gTextMsg_AVR_LIBC_VER_STR[] PROGMEM = __AVR_LIBC_VERSION_STRING__; - const char gTextMsg_GCC_VERSION_STR[] PROGMEM = __VERSION__; - const char gTextMsg_VECTOR_HEADER[] PROGMEM = "V# ADDR op code instruction addr Interrupt"; - const char gTextMsg_noVector[] PROGMEM = "no vector"; - const char gTextMsg_rjmp[] PROGMEM = "rjmp "; - const char gTextMsg_jmp[] PROGMEM = "jmp "; - const char gTextMsg_WHAT_PORT[] PROGMEM = "What port:"; - const char gTextMsg_PortNotSupported[] PROGMEM = "Port not supported"; - const char gTextMsg_MustBeLetter[] PROGMEM = "Must be a letter"; - const char gTextMsg_SPACE[] PROGMEM = " "; - const char gTextMsg_WriteToEEprom[] PROGMEM = "Writting EE"; - const char gTextMsg_ReadingEEprom[] PROGMEM = "Reading EE"; - const char gTextMsg_EEPROMerrorCnt[] PROGMEM = "EE err cnt="; - const char gTextMsg_PORT[] PROGMEM = "PORT"; - - -//************************************************************************ -//* Help messages - const char gTextMsg_HELP_MSG_0[] PROGMEM = "0=Zero addr"; - const char gTextMsg_HELP_MSG_QM[] PROGMEM = "?=CPU stats"; - const char gTextMsg_HELP_MSG_AT[] PROGMEM = "@=EEPROM test"; - const char gTextMsg_HELP_MSG_B[] PROGMEM = "B=Blink LED"; - const char gTextMsg_HELP_MSG_E[] PROGMEM = "E=Dump EEPROM"; - const char gTextMsg_HELP_MSG_F[] PROGMEM = "F=Dump FLASH"; - const char gTextMsg_HELP_MSG_H[] PROGMEM = "H=Help"; - const char gTextMsg_HELP_MSG_L[] PROGMEM = "L=List I/O Ports"; -// const char gTextMsg_HELP_MSG_Q[] PROGMEM = "Q=Quit & jump to user pgm"; - const char gTextMsg_HELP_MSG_Q[] PROGMEM = "Q=Quit"; - const char gTextMsg_HELP_MSG_R[] PROGMEM = "R=Dump RAM"; - const char gTextMsg_HELP_MSG_V[] PROGMEM = "V=show interrupt Vectors"; - const char gTextMsg_HELP_MSG_Y[] PROGMEM = "Y=Port blink"; - - const char gTextMsg_END[] PROGMEM = "*"; - - -//************************************************************************ -void PrintFromPROGMEM(const void *dataPtr, unsigned char offset) -{ -char theChar; - - dataPtr += offset; - - do { - #if (FLASHEND > 0x10000) - theChar = pgm_read_byte_far((uint16_t)dataPtr++); - #else - theChar = pgm_read_byte_near((uint16_t)dataPtr++); - #endif - if (theChar != 0) - { - sendchar(theChar); - } - } while (theChar != 0); -} - -//************************************************************************ -void PrintNewLine(void) -{ - sendchar(0x0d); - sendchar(0x0a); -} - - -//************************************************************************ -void PrintFromPROGMEMln(const void *dataPtr, unsigned char offset) -{ - PrintFromPROGMEM(dataPtr, offset); - - PrintNewLine(); -} - - -//************************************************************************ -void PrintString(char *textString) -{ -char theChar; -int ii; - - theChar = 1; - ii = 0; - while (theChar != 0) - { - theChar = textString[ii]; - if (theChar != 0) - { - sendchar(theChar); - } - ii++; - } -} - -//************************************************************************ -void PrintHexByte(unsigned char theByte) -{ -char theChar; - - theChar = 0x30 + ((theByte >> 4) & 0x0f); - if (theChar > 0x39) - { - theChar += 7; - } - sendchar(theChar ); - - theChar = 0x30 + (theByte & 0x0f); - if (theChar > 0x39) - { - theChar += 7; - } - sendchar(theChar ); -} - -//************************************************************************ -void PrintDecInt(int theNumber, int digitCnt) -{ -int theChar; -int myNumber; - - myNumber = theNumber; - - if ((myNumber > 100) || (digitCnt >= 3)) - { - theChar = 0x30 + myNumber / 100; - sendchar(theChar ); - } - - if ((myNumber > 10) || (digitCnt >= 2)) - { - theChar = 0x30 + ((myNumber % 100) / 10 ); - sendchar(theChar ); - } - theChar = 0x30 + (myNumber % 10); - sendchar(theChar ); -} - - - - -//************************************************************************ -static void PrintCPUstats(void) -{ -unsigned char fuseByte; - - PrintFromPROGMEMln(gTextMsg_Explorer, 0); - - PrintFromPROGMEM(gTextMsg_COMPILED_ON, 0); - PrintFromPROGMEMln(gTextMsg_GCC_DATE_STR, 0); - - PrintFromPROGMEM(gTextMsg_CPU_Type, 0); - PrintFromPROGMEMln(gTextMsg_CPU_Name, 0); - - PrintFromPROGMEM(gTextMsg_AVR_ARCH, 0); - PrintDecInt(__AVR_ARCH__, 1); - PrintNewLine(); - - PrintFromPROGMEM(gTextMsg_GCC_VERSION, 0); - PrintFromPROGMEMln(gTextMsg_GCC_VERSION_STR, 0); - - //* these can be found in avr/version.h - PrintFromPROGMEM(gTextMsg_AVR_LIBC, 0); - PrintFromPROGMEMln(gTextMsg_AVR_LIBC_VER_STR, 0); - -#if defined(SIGNATURE_0) - PrintFromPROGMEM(gTextMsg_CPU_SIGNATURE, 0); - //* these can be found in avr/iomxxx.h - PrintHexByte(SIGNATURE_0); - PrintHexByte(SIGNATURE_1); - PrintHexByte(SIGNATURE_2); - PrintNewLine(); -#endif - - -#if defined(GET_LOW_FUSE_BITS) - //* fuse settings - PrintFromPROGMEM(gTextMsg_FUSE_BYTE_LOW, 0); - fuseByte = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); - PrintHexByte(fuseByte); - PrintNewLine(); - - PrintFromPROGMEM(gTextMsg_FUSE_BYTE_HIGH, 0); - fuseByte = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - PrintHexByte(fuseByte); - PrintNewLine(); - - PrintFromPROGMEM(gTextMsg_FUSE_BYTE_EXT, 0); - fuseByte = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); - PrintHexByte(fuseByte); - PrintNewLine(); - - PrintFromPROGMEM(gTextMsg_FUSE_BYTE_LOCK, 0); - fuseByte = boot_lock_fuse_bits_get(GET_LOCK_BITS); - PrintHexByte(fuseByte); - PrintNewLine(); - -#endif - -} - - -//************************************************************************ -static void BlinkLED(void) -{ - PROGLED_DDR |= (1<<PROGLED_PIN); - PROGLED_PORT |= (1<<PROGLED_PIN); // active high LED ON - - while (!Serial_Available()) - { - PROGLED_PORT &= ~(1<<PROGLED_PIN); // turn LED off - delay_ms(100); - PROGLED_PORT |= (1<<PROGLED_PIN); // turn LED on - delay_ms(100); - } - recchar(); // get the char out of the buffer -} - -enum -{ - kDUMP_FLASH = 0, - kDUMP_EEPROM, - kDUMP_RAM -}; - -//************************************************************************ -static void DumpHex(unsigned char dumpWhat, unsigned long startAddress, unsigned char numRows) -{ -unsigned long myAddressPointer; -uint8_t ii; -unsigned char theValue; -char asciiDump[18]; -unsigned char *ramPtr; - - - ramPtr = 0; - theValue = 0; - myAddressPointer = startAddress; - while (numRows > 0) - { - if (myAddressPointer > 0x10000) - { - PrintHexByte((myAddressPointer >> 16) & 0x00ff); - } - PrintHexByte((myAddressPointer >> 8) & 0x00ff); - PrintHexByte(myAddressPointer & 0x00ff); - sendchar(0x20); - sendchar('-'); - sendchar(0x20); - - asciiDump[0] = 0; - for (ii=0; ii<16; ii++) - { - switch(dumpWhat) - { - case kDUMP_FLASH: - #if (FLASHEND > 0x10000) - theValue = pgm_read_byte_far(myAddressPointer); - #else - theValue = pgm_read_byte_near(myAddressPointer); - #endif - break; - - case kDUMP_EEPROM: - theValue = eeprom_read_byte((uint8_t *)(uint16_t)myAddressPointer); - break; - - case kDUMP_RAM: - theValue = ramPtr[myAddressPointer]; - break; - - } - PrintHexByte(theValue); - sendchar(0x20); - if ((theValue >= 0x20) && (theValue < 0x7f)) - { - asciiDump[ii % 16] = theValue; - } - else - { - asciiDump[ii % 16] = '.'; - } - - myAddressPointer++; - } - asciiDump[16] = 0; - PrintString(asciiDump); - PrintNewLine(); - - numRows--; - } -} - - - -//************************************************************************ -//* returns amount of extended memory -static void EEPROMtest(void) -{ -int ii; -char theChar; -char theEEPROMchar; -int errorCount; - - PrintFromPROGMEMln(gTextMsg_WriteToEEprom, 0); - PrintNewLine(); - ii = 0; -#if (FLASHEND > 0x10000) - while (((theChar = pgm_read_byte_far(((uint16_t)gTextMsg_Explorer) + ii)) != '*') && (ii < 512)) -#else - while (((theChar = pgm_read_byte_near(((uint16_t)gTextMsg_Explorer) + ii)) != '*') && (ii < 512)) -#endif - { - eeprom_write_byte((uint8_t *)ii, theChar); - if (theChar == 0) - { - PrintFromPROGMEM(gTextMsg_SPACE, 0); - } - else - { - sendchar(theChar); - } - ii++; - } - - //* no go back through and test - PrintNewLine(); - PrintNewLine(); - PrintFromPROGMEMln(gTextMsg_ReadingEEprom, 0); - PrintNewLine(); - errorCount = 0; - ii = 0; -#if (FLASHEND > 0x10000) - while (((theChar = pgm_read_byte_far((uint16_t)gTextMsg_Explorer + ii)) != '*') && (ii < 512)) -#else - while (((theChar = pgm_read_byte_near((uint16_t)gTextMsg_Explorer + ii)) != '*') && (ii < 512)) -#endif - { - theEEPROMchar = eeprom_read_byte((uint8_t *)ii); - if (theEEPROMchar == 0) - { - PrintFromPROGMEM(gTextMsg_SPACE, 0); - } - else - { - sendchar(theEEPROMchar); - } - if (theEEPROMchar != theChar) - { - errorCount++; - } - ii++; - } - PrintNewLine(); - PrintNewLine(); - PrintFromPROGMEM(gTextMsg_EEPROMerrorCnt, 0); - PrintDecInt(errorCount, 1); - PrintNewLine(); - PrintNewLine(); - - gEepromIndex = 0; //* set index back to zero for next eeprom dump - -} - - - -#if (FLASHEND > 0x08000) -//* this includes the interrupt names for the monitor portion. There is no longer enough -//* memory to include this -// #include "avrinterruptnames.h" -// #ifndef _INTERRUPT_NAMES_DEFINED_ -// #warning Interrupt vectors not defined -// #endif -#endif - -//************************************************************************ -static void VectorDisplay(void) -{ -unsigned long byte1; -unsigned long byte2; -unsigned long byte3; -unsigned long byte4; -unsigned long word1; -unsigned long word2; -int vectorIndex; -unsigned long myMemoryPtr; -unsigned long wordMemoryAddress; -unsigned long realitiveAddr; -unsigned long myFullAddress; -unsigned long absoluteAddr; -#if defined(_INTERRUPT_NAMES_DEFINED_) - long stringPointer; -#endif - - myMemoryPtr = 0; - vectorIndex = 0; - PrintFromPROGMEMln(gTextMsg_CPU_Name, 0); - PrintFromPROGMEMln(gTextMsg_VECTOR_HEADER, 0); - // V# ADDR op code - // 1 - 0000 = C3 BB 00 00 rjmp 03BB >000776 RESET - while (vectorIndex < kInterruptVectorCount) - { - wordMemoryAddress = myMemoryPtr / 2; - // 01 - 0000 = 12 34 - PrintDecInt(vectorIndex + 1, 2); - sendchar(0x20); - sendchar('-'); - sendchar(0x20); - PrintHexByte((wordMemoryAddress >> 8) & 0x00ff); - PrintHexByte((wordMemoryAddress) & 0x00ff); - sendchar(0x20); - sendchar('='); - sendchar(0x20); - - - //* the AVR is LITTLE ENDIAN, swap the byte order - #if (FLASHEND > 0x10000) - byte1 = pgm_read_byte_far(myMemoryPtr++); - byte2 = pgm_read_byte_far(myMemoryPtr++); - byte3 = pgm_read_byte_far(myMemoryPtr++); - byte4 = pgm_read_byte_far(myMemoryPtr++); - #else - byte1 = pgm_read_byte_near(myMemoryPtr++); - byte2 = pgm_read_byte_near(myMemoryPtr++); - byte3 = pgm_read_byte_near(myMemoryPtr++); - byte4 = pgm_read_byte_near(myMemoryPtr++); - #endif - word1 = (byte2 << 8) + byte1; - word2 = (byte4 << 8) + byte3; - - - PrintHexByte(byte2); - sendchar(0x20); - PrintHexByte(byte1); - sendchar(0x20); - PrintHexByte(byte4); - sendchar(0x20); - PrintHexByte(byte3); - sendchar(0x20); - - if (word1 == 0xffff) - { - PrintFromPROGMEM(gTextMsg_noVector, 0); - } - else if ((word1 & 0xc000) == 0xc000) - { - //* rjmp instruction - realitiveAddr = word1 & 0x3FFF; - absoluteAddr = wordMemoryAddress + realitiveAddr; //* add the offset to the current address - absoluteAddr = absoluteAddr << 1; //* multiply by 2 for byte address - - PrintFromPROGMEM(gTextMsg_rjmp, 0); - PrintHexByte((realitiveAddr >> 8) & 0x00ff); - PrintHexByte((realitiveAddr) & 0x00ff); - sendchar(0x20); - sendchar('>'); - PrintHexByte((absoluteAddr >> 16) & 0x00ff); - PrintHexByte((absoluteAddr >> 8) & 0x00ff); - PrintHexByte((absoluteAddr) & 0x00ff); - - } - else if ((word1 & 0xfE0E) == 0x940c) - { - //* jmp instruction, this is REALLY complicated, refer to the instruction manual (JMP) - myFullAddress = ((byte1 & 0x01) << 16) + - ((byte1 & 0xf0) << 17) + - ((byte2 & 0x01) << 21) + - word2; - - absoluteAddr = myFullAddress << 1; - - PrintFromPROGMEM(gTextMsg_jmp, 0); - PrintHexByte((myFullAddress >> 16) & 0x00ff); - PrintHexByte((myFullAddress >> 8) & 0x00ff); - PrintHexByte((myFullAddress) & 0x00ff); - sendchar(0x20); - sendchar('>'); - PrintHexByte((absoluteAddr >> 16) & 0x00ff); - PrintHexByte((absoluteAddr >> 8) & 0x00ff); - PrintHexByte((absoluteAddr) & 0x00ff); - } - - #if defined(_INTERRUPT_NAMES_DEFINED_) - sendchar(0x20); - #if (FLASHEND > 0x10000) - stringPointer = pgm_read_word_far(&(gInterruptNameTable[vectorIndex])); - #else - stringPointer = pgm_read_word_near(&(gInterruptNameTable[vectorIndex])); - #endif - PrintFromPROGMEM((char *)stringPointer, 0); - #endif - PrintNewLine(); - - vectorIndex++; - } -} - -//************************************************************************ -static void PrintAvailablePort(char thePortLetter) -{ - PrintFromPROGMEM(gTextMsg_PORT, 0); - sendchar(thePortLetter); - PrintNewLine(); -} - -//************************************************************************ -static void ListAvailablePorts(void) -{ - -#ifdef DDRA - PrintAvailablePort('A'); -#endif - -#ifdef DDRB - PrintAvailablePort('B'); -#endif - -#ifdef DDRC - PrintAvailablePort('C'); -#endif - -#ifdef DDRD - PrintAvailablePort('D'); -#endif - -#ifdef DDRE - PrintAvailablePort('E'); -#endif - -#ifdef DDRF - PrintAvailablePort('F'); -#endif - -#ifdef DDRG - PrintAvailablePort('G'); -#endif - -#ifdef DDRH - PrintAvailablePort('H'); -#endif - -#ifdef DDRI - PrintAvailablePort('I'); -#endif - -#ifdef DDRJ - PrintAvailablePort('J'); -#endif - -#ifdef DDRK - PrintAvailablePort('K'); -#endif - -#ifdef DDRL - PrintAvailablePort('L'); -#endif - -} - -//************************************************************************ -static void AVR_PortOutput(void) -{ -char portLetter; -char getCharFlag; - - PrintFromPROGMEM(gTextMsg_WHAT_PORT, 0); - - portLetter = recchar(); - portLetter = portLetter & 0x5f; - sendchar(portLetter); - PrintNewLine(); - - if ((portLetter >= 'A') && (portLetter <= 'Z')) - { - getCharFlag = true; - switch(portLetter) - { - #ifdef DDRA - case 'A': - DDRA = 0xff; - while (!Serial_Available()) - { - PORTA ^= 0xff; - delay_ms(200); - } - PORTA = 0; - break; - #endif - - #ifdef DDRB - case 'B': - DDRB = 0xff; - while (!Serial_Available()) - { - PORTB ^= 0xff; - delay_ms(200); - } - PORTB = 0; - break; - #endif - - #ifdef DDRC - case 'C': - DDRC = 0xff; - while (!Serial_Available()) - { - PORTC ^= 0xff; - delay_ms(200); - } - PORTC = 0; - break; - #endif - - #ifdef DDRD - case 'D': - DDRD = 0xff; - while (!Serial_Available()) - { - PORTD ^= 0xff; - delay_ms(200); - } - PORTD = 0; - break; - #endif - - #ifdef DDRE - case 'E': - DDRE = 0xff; - while (!Serial_Available()) - { - PORTE ^= 0xff; - delay_ms(200); - } - PORTE = 0; - break; - #endif - - #ifdef DDRF - case 'F': - DDRF = 0xff; - while (!Serial_Available()) - { - PORTF ^= 0xff; - delay_ms(200); - } - PORTF = 0; - break; - #endif - - #ifdef DDRG - case 'G': - DDRG = 0xff; - while (!Serial_Available()) - { - PORTG ^= 0xff; - delay_ms(200); - } - PORTG = 0; - break; - #endif - - #ifdef DDRH - case 'H': - DDRH = 0xff; - while (!Serial_Available()) - { - PORTH ^= 0xff; - delay_ms(200); - } - PORTH = 0; - break; - #endif - - #ifdef DDRI - case 'I': - DDRI = 0xff; - while (!Serial_Available()) - { - PORTI ^= 0xff; - delay_ms(200); - } - PORTI = 0; - break; - #endif - - #ifdef DDRJ - case 'J': - DDRJ = 0xff; - while (!Serial_Available()) - { - PORTJ ^= 0xff; - delay_ms(200); - } - PORTJ = 0; - break; - #endif - - #ifdef DDRK - case 'K': - DDRK = 0xff; - while (!Serial_Available()) - { - PORTK ^= 0xff; - delay_ms(200); - } - PORTK = 0; - break; - #endif - - #ifdef DDRL - case 'L': - DDRL = 0xff; - while (!Serial_Available()) - { - PORTL ^= 0xff; - delay_ms(200); - } - PORTL = 0; - break; - #endif - - default: - PrintFromPROGMEMln(gTextMsg_PortNotSupported, 0); - getCharFlag = false; - break; - } - if (getCharFlag) - { - recchar(); - } - } - else - { - PrintFromPROGMEMln(gTextMsg_MustBeLetter, 0); - } -} - - -//******************************************************************* -static void PrintHelp(void) -{ - PrintFromPROGMEMln(gTextMsg_HELP_MSG_0, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_QM, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_AT, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_B, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_E, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_F, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_H, 0); - - PrintFromPROGMEMln(gTextMsg_HELP_MSG_L, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_Q, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_R, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_V, 0); - PrintFromPROGMEMln(gTextMsg_HELP_MSG_Y, 0); -} - -//************************************************************************ -static void RunMonitor(void) -{ -char keepGoing; -unsigned char theChar; -int ii, jj; - - for (ii=0; ii<5; ii++) - { - for (jj=0; jj<25; jj++) - { - sendchar('!'); - } - PrintNewLine(); - } - - gRamIndex = 0; - gFlashIndex = 0; - gEepromIndex = 0; - - PrintFromPROGMEMln(gTextMsg_Explorer, 0); - - keepGoing = 1; - while (keepGoing) - { - PrintFromPROGMEM(gTextMsg_Prompt, 0); - theChar = recchar(); - if (theChar >= 0x60) - { - theChar = theChar & 0x5F; - } - - if (theChar >= 0x20) - { - sendchar(theChar); - sendchar(0x20); - } - - switch(theChar) - { - case '0': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_0, 2); - gFlashIndex = 0; - gRamIndex = 0; - gEepromIndex = 0; - break; - - case '?': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_QM, 2); - PrintCPUstats(); - break; - - case '@': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_AT, 2); - EEPROMtest(); - break; - - case 'B': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_B, 2); - BlinkLED(); - break; - - case 'E': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_E, 2); - DumpHex(kDUMP_EEPROM, gEepromIndex, 16); - gEepromIndex += 256; - if (gEepromIndex > E2END) - { - gEepromIndex = 0; - } - break; - - case 'F': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_F, 2); - DumpHex(kDUMP_FLASH, gFlashIndex, 16); - gFlashIndex += 256; - break; - - case 'H': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_H, 2); - PrintHelp(); - break; - - case 'L': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_L, 2); - ListAvailablePorts(); - break; - - case 'Q': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_Q, 2); - keepGoing = false; - break; - - case 'R': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_R, 2); - DumpHex(kDUMP_RAM, gRamIndex, 16); - gRamIndex += 256; - break; - - case 'V': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_V, 2); - VectorDisplay(); - break; - - case 'Y': - PrintFromPROGMEMln(gTextMsg_HELP_MSG_Y, 2); - AVR_PortOutput(); - break; - - default: - PrintFromPROGMEMln(gTextMsg_HUH, 0); - break; - } - } -} - -#endif - |