aboutsummaryrefslogtreecommitdiff
path: root/bootloaders/stk500v2/stk500boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloaders/stk500v2/stk500boot.c')
-rw-r--r--bootloaders/stk500v2/stk500boot.c2122
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
-