Version 0.2 (20040324)
This commit is contained in:
commit
744684bb88
79
bin/m16_uart_boot_3_9.hex
Normal file
79
bin/m16_uart_boot_3_9.hex
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
:103800000C942A1C0C94451C0C94451C0C94451CCF
|
||||||
|
:103810000C94451C0C94451C0C94451C0C94451CA4
|
||||||
|
:103820000C94451C0C94451C0C94451C0C94451C94
|
||||||
|
:103830000C94451C0C94451C0C94451C0C94451C84
|
||||||
|
:103840000C94451C0C94451C0C94451C0C94451C74
|
||||||
|
:103850000C94451C11241FBECFE5D4E0DEBFCDBFC4
|
||||||
|
:1038600010E0A0E6B0E0E4ECFCE302C005900D92AD
|
||||||
|
:10387000A036B107D9F710E0A0E6B0E001C01D9274
|
||||||
|
:10388000A336B107E1F70C945D1C0C94001C81E495
|
||||||
|
:103890000E94391E86E50E94391E82E50E94391E6B
|
||||||
|
:1038A00082E40E94391E8FE40E94391E8FE40E9438
|
||||||
|
:1038B000391E84E50E94391E0895CFE5D4E0DEBFAD
|
||||||
|
:1038C000CDBFC0E0D0E001E08FEF8BBB60E08BE0CC
|
||||||
|
:1038D00090E00E942F1E05BF82E085BFCF9B06C0EF
|
||||||
|
:1038E00081E085BF15BEFE0109950FC00E944E1EE6
|
||||||
|
:1038F0008B3141F40E944E1E8335E1F70E94471C34
|
||||||
|
:1039000000E003C08FE30E94391E002339F70E94B4
|
||||||
|
:103910004E1E682F813611F489E5B7C08134A9F4B1
|
||||||
|
:103920000E944E1E99279093610080936000182F8B
|
||||||
|
:1039300000270E944E1E9927082B192B000F111FDC
|
||||||
|
:1039400010936100009360005CC0823641F489E509
|
||||||
|
:103950000E94391E80E00E94391E80E896C08234A1
|
||||||
|
:1039600089F40E944E1E9927182F00270E944E1E90
|
||||||
|
:103970009927082B192B0E944E1E682FC8010E9400
|
||||||
|
:10398000481D83C0873689F40E944E1E9927182F40
|
||||||
|
:1039900000270E944E1E9927082B192B0E944E1EAD
|
||||||
|
:1039A000682FC8010E94C31DB2CF853661F5809192
|
||||||
|
:1039B00062008537F9F4109261001092600063E0B4
|
||||||
|
:1039C00080916000909161000E94FE1D61E18091F4
|
||||||
|
:1039D0006000909161000E94FE1D809160009091B6
|
||||||
|
:1039E000610080589F4F90936100809360008050E9
|
||||||
|
:1039F000984328F361E180916000909161000E94FA
|
||||||
|
:103A0000FE1D8DE042C0853451F488E190E028E04D
|
||||||
|
:103A10000FB6F894A89581BD0FBE21BDF2CF8035B9
|
||||||
|
:103A200081F38C3471F3803711F483E52EC0843731
|
||||||
|
:103A300029F485E70E94391E80E027C0885782302C
|
||||||
|
:103A400018F40E944E1EDDCF643529F40E944E1EEC
|
||||||
|
:103A500080936200D6CF633519F40E94471C57CF7C
|
||||||
|
:103A6000663529F480E30E94391E82E30EC0633775
|
||||||
|
:103A700041F483E00E94391E84E90E94391E8EE1E0
|
||||||
|
:103A800004C06B3109F443CF8FE30E94391E3FCF4E
|
||||||
|
:103A9000DF92EF92FF920F931F93CF93DF937C01FE
|
||||||
|
:103AA000D62EC0916000D091610080916200853770
|
||||||
|
:103AB00009F05FC086E46817D1F50E944E1E082FFA
|
||||||
|
:103AC00011270E944E1E9927982F8827082B192B03
|
||||||
|
:103AD0006091600070916100C8010E940D1E80918C
|
||||||
|
:103AE0006000909161000296909361008093600065
|
||||||
|
:103AF0008EEF9FEFE80EF91EE114F104F1F6C078A5
|
||||||
|
:103B000065E0CE010E94FE1D61E1CE010E94FE1D16
|
||||||
|
:103B100080916000909161009C012078821793074A
|
||||||
|
:103B200031F020583F4F309361002093600095E4BE
|
||||||
|
:103B3000D916E1F4809160008EBB80916000909175
|
||||||
|
:103B40006100292F33272FBB01969093610080934A
|
||||||
|
:103B500060000E944E1E8DBBE29AE19AE199FECF71
|
||||||
|
:103B60000894E108F108E114F10421F78DE090E0F8
|
||||||
|
:103B700002C080E090E0DF91CF911F910F91FF9004
|
||||||
|
:103B8000EF90DF9008950F931F93CF93DF93EC0195
|
||||||
|
:103B90006534B1F4809160008EBB8091600090919B
|
||||||
|
:103BA0006100292F33272FBB0196909361008093EA
|
||||||
|
:103BB0006000E09A8DB30E94391E219759F719C011
|
||||||
|
:103BC00060E080916000909161000E94201E8C0155
|
||||||
|
:103BD0000E94391E812F99270E94391E8091600012
|
||||||
|
:103BE000909161000296909361008093600022970B
|
||||||
|
:103BF00039F7DF91CF911F910F91089507B600FC1F
|
||||||
|
:103C0000FDCFE199FECFFC0160935700E895FFFFDF
|
||||||
|
:103C1000000007B600FCFDCF08959C0107B600FC2C
|
||||||
|
:103C2000FDCFE199FECF81E00901FB0180935700B0
|
||||||
|
:103C3000E895FFFF0000112407B600FCFDCF0895B2
|
||||||
|
:103C400007B600FCFDCFE199FECFFC0160FD60935B
|
||||||
|
:103C50005700C895802DE395C895902D08959C0137
|
||||||
|
:103C6000832F992780BD29B988E18AB986E880BD6C
|
||||||
|
:103C7000089520E030E08CB90FB607FE0BC05E99C6
|
||||||
|
:103C80000BC02F5F3F4F5E9907C087E22031380796
|
||||||
|
:103C9000C4F302C05E9BFECF5E9A089580E090E080
|
||||||
|
:103CA0000FB607FE0AC05F990AC001965F9907C068
|
||||||
|
:103CB00027E280319207CCF302C05F9BFECF8CB12C
|
||||||
|
:043CC00099270895A3
|
||||||
|
:0400000300003800C1
|
||||||
|
:00000001FF
|
129
chipdef.h
Normal file
129
chipdef.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
#ifndef CHIPDEF_H
|
||||||
|
#define CHIPDEF_H
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega169__)
|
||||||
|
#define sig_byte3 0x1E
|
||||||
|
#define sig_byte2 0x94
|
||||||
|
#define sig_byte1 0x05
|
||||||
|
|
||||||
|
#define devtype 0x79 // Mega 169 device code
|
||||||
|
|
||||||
|
#define PAGESIZE 128 // 2*64 Words = Size in Bytes
|
||||||
|
|
||||||
|
#ifdef _B128
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*128 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B256
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*256 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B512
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*512 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B1024
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*1024 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B2048
|
||||||
|
#error "_B2048 not suppoted on this device"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__AVR_ATmega16__)
|
||||||
|
|
||||||
|
#define sig_byte3 0x1E
|
||||||
|
#define sig_byte2 0x94
|
||||||
|
#define sig_byte1 0x03
|
||||||
|
|
||||||
|
#define devtype 0x75 // Mega16 device code
|
||||||
|
|
||||||
|
#define PAGESIZE 128 // Size in Bytes
|
||||||
|
|
||||||
|
#ifdef _B128
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*128 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B256
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*256 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B512
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*512 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B1024
|
||||||
|
#define APP_PAGES ((2*8192 / PAGESIZE)- (2*1024 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B2048
|
||||||
|
#error "_B2048 not suppoted on this device"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__AVR_ATmega8__)
|
||||||
|
|
||||||
|
#define sig_byte3 0x1E
|
||||||
|
#define sig_byte2 0x93
|
||||||
|
#define sig_byte1 0x07
|
||||||
|
|
||||||
|
#define devtype 0x77 // Mega8 boot device code
|
||||||
|
|
||||||
|
#define PAGESIZE 64 // Size in Bytes
|
||||||
|
|
||||||
|
#ifdef _B128
|
||||||
|
#define APP_PAGES ((2*4096 / PAGESIZE)- (2*128 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B256
|
||||||
|
#define APP_PAGES ((2*4096 / PAGESIZE)- (2*256 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B512
|
||||||
|
#define APP_PAGES ((2*4096 / PAGESIZE)- (2*512 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B1024
|
||||||
|
#define APP_PAGES ((2*4096 / PAGESIZE)- (2*1024 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B2048
|
||||||
|
#error "_B2048 not suppoted on this device"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__AVR_ATmega32__)
|
||||||
|
|
||||||
|
#define sig_byte3 0x1E
|
||||||
|
#define sig_byte2 0x95
|
||||||
|
#define sig_byte1 0x02
|
||||||
|
|
||||||
|
#define devtype 0x73 // Mega32 device code
|
||||||
|
|
||||||
|
#define PAGESIZE 128 // Size in Bytes
|
||||||
|
|
||||||
|
#ifdef _B128
|
||||||
|
#define APP_PAGES ((2*16384 / PAGESIZE)- (2*128 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B256
|
||||||
|
#define APP_PAGES ((2*16384 / PAGESIZE)- (2*256 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B512
|
||||||
|
#define APP_PAGES ((2*16384 / PAGESIZE)- (2*512 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B1024
|
||||||
|
#define APP_PAGES ((2*16384 / PAGESIZE)- (2*1024 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
#ifdef _B2048
|
||||||
|
#define APP_PAGES ((2*16384 / PAGESIZE)- (2*2048 / PAGESIZE ))
|
||||||
|
#define APP_END APP_PAGES * PAGESIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "no definition for MCU available in chipdef.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
156
lowlevel.c
Normal file
156
lowlevel.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
//
|
||||||
|
// Low-level bootloader routines to replace "assembly.s90"
|
||||||
|
// from the original ATMEL code.
|
||||||
|
//
|
||||||
|
// See avr-libc's boot-module for more information
|
||||||
|
// Thanks to Eric B. Weddington author of boot.h.
|
||||||
|
//
|
||||||
|
// 3/2004 Martin Thomas, Kaiserslautern, Germany
|
||||||
|
//
|
||||||
|
// todo: extend functions with espm
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
// There are some #ifdefs in avr/boot.h V1.0 that do not "know"
|
||||||
|
// about the ATmega169. So some functions have been copied here
|
||||||
|
// and small modifications have been done to avoid problems.
|
||||||
|
|
||||||
|
#include "chipdef.h"
|
||||||
|
|
||||||
|
/* Check for SPM Control Register in processor. */
|
||||||
|
#if defined (SPMCSR)
|
||||||
|
# define SPM_REG SPMCSR
|
||||||
|
#elif defined (SPMCR)
|
||||||
|
# define SPM_REG SPMCR
|
||||||
|
#else
|
||||||
|
# error AVR processor does not provide bootloader support!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BOOT_PAGE_FILL _BV(SPMEN)
|
||||||
|
#define BOOT_LOCK_BITS_SET (_BV(SPMEN) | _BV(BLBSET))
|
||||||
|
|
||||||
|
#define boot_spm_busy() (SPM_REG & (unsigned char)_BV(SPMEN))
|
||||||
|
#define boot_spm_busy_wait() do{}while(boot_spm_busy())
|
||||||
|
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
|
||||||
|
#define eeprom_is_ready_wait() do{}while(!eeprom_is_ready())
|
||||||
|
|
||||||
|
// from avr/boot.h
|
||||||
|
// added "func" parameter and spm-busy check at end
|
||||||
|
#define _boot_page_write_alternate_bf(address,func) \
|
||||||
|
({ \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_is_ready_wait(); \
|
||||||
|
asm volatile \
|
||||||
|
( \
|
||||||
|
"movw r30, %2\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: "=m" (SPM_REG) \
|
||||||
|
: "r" ((unsigned char)func), \
|
||||||
|
"r" ((unsigned short)address) \
|
||||||
|
: "r30", "r31", "r0" \
|
||||||
|
); \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
})
|
||||||
|
|
||||||
|
// from avr/boot.h
|
||||||
|
// added spm-busy check at end
|
||||||
|
#define _boot_page_fill_alternate_bf(address, data)\
|
||||||
|
({ \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_is_ready_wait(); \
|
||||||
|
asm volatile \
|
||||||
|
( \
|
||||||
|
"movw r0, %3\n\t" \
|
||||||
|
"movw r30, %2\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: "=m" (SPM_REG) \
|
||||||
|
: "r" ((unsigned char)BOOT_PAGE_FILL), \
|
||||||
|
"r" ((unsigned short)address), \
|
||||||
|
"r" ((unsigned short)data) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
})
|
||||||
|
|
||||||
|
// from avr/boot.h
|
||||||
|
// added spm-busy check at end, removed lockbit-masking,
|
||||||
|
// removed r30/r31 init - maybe wrong TODO: test this
|
||||||
|
|
||||||
|
#ifdef ENABLEREADFUSELOCK
|
||||||
|
#define _boot_lock_bits_set_alternate_bf(lock_bits) \
|
||||||
|
({ \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_is_ready_wait(); \
|
||||||
|
asm volatile \
|
||||||
|
( \
|
||||||
|
"mov r0, %2\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: "=m" (SPM_REG) \
|
||||||
|
: "r" ((unsigned char)BOOT_LOCK_BITS_SET), \
|
||||||
|
"r" ((unsigned char) lock_bits) \
|
||||||
|
: "r0" \
|
||||||
|
); \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
})
|
||||||
|
|
||||||
|
void write_lock_bits (unsigned char val)
|
||||||
|
{
|
||||||
|
_boot_lock_bits_set_alternate_bf(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void write_page (unsigned int adr, unsigned char function)
|
||||||
|
{
|
||||||
|
_boot_page_write_alternate_bf(adr,function);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_temp_buffer (unsigned int data,unsigned int adr)
|
||||||
|
{
|
||||||
|
_boot_page_fill_alternate_bf(adr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int read_program_memory(unsigned int adr ,unsigned char param)
|
||||||
|
// to read lockbits give param=0x09, if param!=0 it is written to SPMCSR
|
||||||
|
// this is a "translation" from the original code to gcc-inline-assembler
|
||||||
|
{
|
||||||
|
unsigned int retval;
|
||||||
|
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
eeprom_is_ready_wait();
|
||||||
|
asm volatile
|
||||||
|
(
|
||||||
|
"movw r30, %3\n\t"
|
||||||
|
"sbrc %2,0x00\n\t"
|
||||||
|
"sts %0, %2\n\t"
|
||||||
|
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ
|
||||||
|
"elpm\n\t" // read LSB
|
||||||
|
#else
|
||||||
|
"lpm\n\t" // R0 is now the LSB of the return value
|
||||||
|
#endif
|
||||||
|
"mov %A1,r0\n\t"
|
||||||
|
"inc r30\n\t"
|
||||||
|
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ
|
||||||
|
"elpm\n\t" // read MSB
|
||||||
|
#else
|
||||||
|
"lpm\n\t" // R0 is now the MSB of the return value
|
||||||
|
#endif
|
||||||
|
"mov %B1,r0\n\t"
|
||||||
|
: "=m" (SPM_REG),
|
||||||
|
"=r" (retval)
|
||||||
|
: "r" ((unsigned char)param),
|
||||||
|
"r" ((unsigned short)adr)
|
||||||
|
: "r30", "r31", "r0"
|
||||||
|
);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
9
lowlevel.h
Normal file
9
lowlevel.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef LOWLEVEL_H
|
||||||
|
#define LOWLEVEL_H
|
||||||
|
void write_page (unsigned int adr, unsigned char function);
|
||||||
|
unsigned int read_program_memory (unsigned int,unsigned char);
|
||||||
|
void fill_temp_buffer (unsigned int data,unsigned int adr);
|
||||||
|
#ifdef ENABLEREADFUSELOCK
|
||||||
|
void write_lock_bits (unsigned char val);
|
||||||
|
#endif
|
||||||
|
#endif
|
446
main.c
Normal file
446
main.c
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* AVRPROG compatible boot-loader
|
||||||
|
* Version : 0.2 (24. March 2004)
|
||||||
|
* Compiler : avr-gcc 3.3.1 / avr-libc 1.0
|
||||||
|
* size : ca. 610 word ( larger than 512 words :-( )
|
||||||
|
* by : Martin Thomas, Kaiserslautern, Germany
|
||||||
|
* eversmith@heizung-thomas.de
|
||||||
|
*
|
||||||
|
* based on the Butterfly Bootloader-Code
|
||||||
|
* Copyright (C) 1996-1998 Atmel Corporation
|
||||||
|
* Author(s) : BBrandal, PKastnes, ARodland, LHM
|
||||||
|
*
|
||||||
|
* The orignal code has been made available by ATMEL together with the
|
||||||
|
* Butterfly application code. Since ATMEL.NO had no problem with
|
||||||
|
* the application gcc-port they hopefully will not have any concerns about
|
||||||
|
* publishing this port. Make sure to keep the copyright notice in derived
|
||||||
|
* work to avoid trouble.
|
||||||
|
****************************************************************************
|
||||||
|
*
|
||||||
|
* Many functions used by "AVRPROG" (fuses) have been disabled by ATMEL in
|
||||||
|
* the original source code of the Butterfly Boot-loader not by me.
|
||||||
|
* Please 'diff' against the original source to see everything that has been
|
||||||
|
* changed for the gcc port.
|
||||||
|
*
|
||||||
|
* The boot interrupt vector is included (this bootloader is completly in
|
||||||
|
* ".text" section). If you need this space for further functions you have to
|
||||||
|
* add a separate section for the bootloader-functions and add an attribute
|
||||||
|
* for this section to _all_ function prototypes of functions in the loader.
|
||||||
|
* With this the interrupt vector will be placed at .0000 and the bootloader
|
||||||
|
* code (without interrupt vector) at the adress you define in the linker
|
||||||
|
* options for the newly created section. See the avr-libc FAQ and the avr-
|
||||||
|
* libc's avr/boot.h documentation for further details.
|
||||||
|
*
|
||||||
|
* For this bootloader a Boot-Size of at least 0x4C4 (1220) bytes =
|
||||||
|
* 610 words is needed. Sorry, so far efforts to shrink to 512 words failed.
|
||||||
|
* See the makefile for information how to adopt the linker-settings to
|
||||||
|
* the selected Boot Size (_Bxxx below)
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/signal.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* READFUSELOCK is untested, will not work for Mega169 since not
|
||||||
|
supported by AVRPROG 1.37 */
|
||||||
|
// #define ENABLEREADFUSELOCK
|
||||||
|
|
||||||
|
#define BAUDRATE 19200
|
||||||
|
#define XTAL 3686400
|
||||||
|
|
||||||
|
/* Select Boot Size (select one, comment out the others)
|
||||||
|
select at least _B1024 */
|
||||||
|
// NO! #define _B128
|
||||||
|
// NO! #define _B256
|
||||||
|
// NO! #define _B512
|
||||||
|
#define _B1024
|
||||||
|
//#define _B2048
|
||||||
|
|
||||||
|
#include "chipdef.h"
|
||||||
|
|
||||||
|
#define UART_RX_BUFFER_SIZE PAGESIZE
|
||||||
|
|
||||||
|
#include "lowlevel.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
unsigned char BufferLoad(unsigned int , unsigned char ) ;
|
||||||
|
void BlockRead(unsigned int , unsigned char ) ;
|
||||||
|
|
||||||
|
unsigned int address;
|
||||||
|
unsigned char device;
|
||||||
|
|
||||||
|
void send_boot(void)
|
||||||
|
{
|
||||||
|
sendchar('A');
|
||||||
|
sendchar('V');
|
||||||
|
sendchar('R');
|
||||||
|
sendchar('B');
|
||||||
|
sendchar('O');
|
||||||
|
sendchar('O');
|
||||||
|
sendchar('T');
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
void (*funcptr)( void ) = 0x0000; // Set up function pointer
|
||||||
|
|
||||||
|
unsigned int tempi;
|
||||||
|
char val;
|
||||||
|
char OK = 1;
|
||||||
|
|
||||||
|
PORTA = 0xFF; // Enable pullups on Port A
|
||||||
|
|
||||||
|
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE);
|
||||||
|
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE);
|
||||||
|
|
||||||
|
MCUCR = (1<<IVCE);
|
||||||
|
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector
|
||||||
|
|
||||||
|
/* This is an adoption of the Butterfly Bootloader startup-sequence.
|
||||||
|
It may look a little strange but separating the login-loop from
|
||||||
|
the main parser-loop gives a lot a possibilities (timeout, sleep-modes
|
||||||
|
etc.).
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(;OK;)
|
||||||
|
{
|
||||||
|
if((PINA & (1<<PINA7)))
|
||||||
|
{
|
||||||
|
// jump to main app if PIN A0 is not grounded
|
||||||
|
MCUCR = (1<<IVCE);
|
||||||
|
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
|
||||||
|
funcptr(); // Jump to application sector
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = recchar();
|
||||||
|
|
||||||
|
if( val == 0x1B)
|
||||||
|
{ // AVRPROG connection
|
||||||
|
while (val != 'S') // Wait for signon
|
||||||
|
{
|
||||||
|
val = recchar();
|
||||||
|
}
|
||||||
|
send_boot(); // Report signon
|
||||||
|
OK = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sendchar('?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
val=recchar();
|
||||||
|
|
||||||
|
if(val=='a') //Autoincrement?
|
||||||
|
{
|
||||||
|
sendchar('Y'); //Autoincrement is quicker
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='A') //write address
|
||||||
|
{
|
||||||
|
address=recchar(); //read address 8 MSB
|
||||||
|
address=(address<<8)|recchar();
|
||||||
|
|
||||||
|
address=address<<1; //convert from word address to byte address
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='b')
|
||||||
|
{ // Buffer load support
|
||||||
|
sendchar('Y'); // Report buffer load supported
|
||||||
|
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
|
||||||
|
// Report buffer size in bytes
|
||||||
|
sendchar(UART_RX_BUFFER_SIZE & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='B') // Start buffer load
|
||||||
|
{
|
||||||
|
tempi = recchar() << 8; // Load high byte of buffersize
|
||||||
|
tempi |= recchar(); // Load low byte of buffersize
|
||||||
|
val = recchar(); // Load memory type ('E' or 'F')
|
||||||
|
sendchar (BufferLoad(tempi,val));
|
||||||
|
// Start downloading of buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val == 'g') // Block read
|
||||||
|
{
|
||||||
|
tempi = (recchar() << 8) | recchar();
|
||||||
|
|
||||||
|
val = recchar(); // Get memtype
|
||||||
|
BlockRead(tempi,val); // Perform the block read
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if(val=='c') //Write program memory, low byte
|
||||||
|
{
|
||||||
|
ldata=recchar();
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val== 'C') //Write program memory, high byte
|
||||||
|
{
|
||||||
|
data=ldata|(recchar()<<8);
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
fill_temp_buffer(data,(address)); //call asm routine.
|
||||||
|
}
|
||||||
|
address=address+2;
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else if(val=='e') //Chip erase
|
||||||
|
{
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
for(address=0;address < APP_END;address += PAGESIZE) //Application section = 60 pages
|
||||||
|
{
|
||||||
|
write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
|
||||||
|
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='E') //Exit upgrade
|
||||||
|
{
|
||||||
|
// WDTCR = (1<<WDTCE) | (1<<WDE); //Enable Watchdog Timer to give reset
|
||||||
|
wdt_enable(WDTO_15MS);
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if(val=='l') // write lockbits
|
||||||
|
{
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
write_lock_bits(recchar());
|
||||||
|
}
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val== 'm') // write page
|
||||||
|
{
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
|
||||||
|
write_page((address),0x05);
|
||||||
|
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
|
||||||
|
}
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if(val=='P') // Enter programming mode
|
||||||
|
{
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='L') // Leave programming mode
|
||||||
|
{
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else if (val=='p') // mt: return programmer type
|
||||||
|
{
|
||||||
|
sendchar('S'); // serial programmer
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
else if(val=='R') //Read program memory
|
||||||
|
{
|
||||||
|
write_page(0,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
|
||||||
|
// SPMCSR = (1<<RWWSRE) | (1<<SPMEN);
|
||||||
|
// __store_program_memory();
|
||||||
|
// while((SPMCSR & 0x01));
|
||||||
|
|
||||||
|
intval=read_program_memory(address,0x00);
|
||||||
|
sendchar((char)(intval>>8)); //send MSB
|
||||||
|
sendchar((char)intval); //send LSB
|
||||||
|
address=address+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val == 'D') // write EEPROM
|
||||||
|
{
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
EEARL = address;
|
||||||
|
EEARH = (address >> 8);
|
||||||
|
address++;
|
||||||
|
EEDR = recchar();
|
||||||
|
EECR |= (1<<EEMWE);
|
||||||
|
EECR |= (1<<EEWE);
|
||||||
|
while (EECR & (1<<EEWE))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val == 'd') // read eeprom
|
||||||
|
{
|
||||||
|
EEARL = address;
|
||||||
|
EEARH = (address >> 8);
|
||||||
|
address++;
|
||||||
|
EECR |= (1<<EERE);
|
||||||
|
sendchar(EEDR);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#ifdef ENABLEREADFUSELOCK
|
||||||
|
#warning "Extension 'ReadFuseLock' enabled"
|
||||||
|
// mt TODO: Read fuse bit seems to work for clock speed, other settings are not
|
||||||
|
// interpreted correctly. Locks and high fuse do not work at all (in AVRPROG 1.37)
|
||||||
|
// Reason for this should be the difference between ATmega16 and ATmega169.
|
||||||
|
// AVRPROG interprets the results as from an ATmega16 while they are from an ATmega169
|
||||||
|
else if(val=='F') // read fuse bits
|
||||||
|
{
|
||||||
|
sendchar(read_program_memory(0x0000,0x09)); // 0x09 for (1<<BLBSET)|(1<<SPMEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='r') // read lock bits
|
||||||
|
{
|
||||||
|
sendchar(read_program_memory(0x0001,0x09));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='N') // read high fuse bits
|
||||||
|
{
|
||||||
|
// mt sendchar(read_program_memory(0x0003));
|
||||||
|
sendchar(read_program_memory(0x0003,0x09));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val=='Q') // read extended fuse bits
|
||||||
|
{
|
||||||
|
sendchar(read_program_memory(0x0002,0x09));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// end of ENABLEREADFUSELOCK section
|
||||||
|
|
||||||
|
else if(val=='t') // Return programmer type
|
||||||
|
{
|
||||||
|
sendchar(devtype);
|
||||||
|
sendchar(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((val=='x')||(val=='y')) // clear and set LED ignored
|
||||||
|
{
|
||||||
|
recchar();
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val=='T') // set device/programmer type in bootloader (?)
|
||||||
|
{
|
||||||
|
device = recchar();
|
||||||
|
sendchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val=='S') // Return software identifier
|
||||||
|
{
|
||||||
|
send_boot();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val=='V') // Return Software Version
|
||||||
|
{
|
||||||
|
sendchar('0'); // mt: changed from 2;0 to 0;1
|
||||||
|
sendchar('2');
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (val=='s') // Return Signature Byte
|
||||||
|
{
|
||||||
|
sendchar(sig_byte1);
|
||||||
|
sendchar(sig_byte2);
|
||||||
|
sendchar(sig_byte3);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(val!=0x1b) // if not esc
|
||||||
|
{
|
||||||
|
sendchar('?');
|
||||||
|
}
|
||||||
|
} // "parser" for-loop
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char BufferLoad(unsigned int size, unsigned char mem)
|
||||||
|
{
|
||||||
|
int data, tempaddress;
|
||||||
|
|
||||||
|
tempaddress = address; // Store address in page
|
||||||
|
|
||||||
|
if (device == devtype)
|
||||||
|
{
|
||||||
|
if (mem == 'F')
|
||||||
|
{
|
||||||
|
|
||||||
|
do {
|
||||||
|
data = recchar();
|
||||||
|
data |= (recchar() << 8);
|
||||||
|
fill_temp_buffer(data,(address));
|
||||||
|
//call asm routine.
|
||||||
|
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
|
||||||
|
|
||||||
|
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
|
||||||
|
write_page((tempaddress),0x05); // Program page contents
|
||||||
|
|
||||||
|
write_page(tempaddress,(1<<RWWSRE) + (1<<SPMEN));
|
||||||
|
//Re-enable the RWW section
|
||||||
|
if (address != (address & 0xFF80))
|
||||||
|
{ // Ensure that the address points to the beginning of the next page
|
||||||
|
address &= 0xFF80;
|
||||||
|
address += PAGESIZE;
|
||||||
|
}
|
||||||
|
} // End FLASH
|
||||||
|
|
||||||
|
if (mem == 'E') // Start EEPROM
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
EEARL = address; // Setup EEPROM address
|
||||||
|
EEARH = (address >> 8);
|
||||||
|
address++; // Select next byte
|
||||||
|
EEDR = recchar(); // Load data to write
|
||||||
|
EECR |= (1<<EEMWE); // Write data into EEPROM
|
||||||
|
EECR |= (1<<EEWE);
|
||||||
|
while (EECR & (1<<EEWE)) // Wait for EEPROM write to finish
|
||||||
|
;
|
||||||
|
size--; // Decreas number of bytes to write
|
||||||
|
} while(size); // Loop until all bytes written
|
||||||
|
}
|
||||||
|
return '\r'; // Report programming OK
|
||||||
|
}
|
||||||
|
return 0; // Report programming failed
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockRead(unsigned int size, unsigned char mem)
|
||||||
|
{
|
||||||
|
unsigned int data;
|
||||||
|
|
||||||
|
if (mem == 'E') // Read EEPROM
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
EEARL = address; // Setup EEPROM address
|
||||||
|
EEARH = (address >> 8);
|
||||||
|
address++; // Select next EEPROM byte
|
||||||
|
EECR |= (1<<EERE); // Read EEPROM
|
||||||
|
sendchar(EEDR); // Transmit EEPROM data to PC
|
||||||
|
size--; // Decrease number of bytes to read
|
||||||
|
} while (size); // Repeat until all block has been read
|
||||||
|
}
|
||||||
|
else // Read Flash
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
data = read_program_memory(address,0x00);
|
||||||
|
sendchar((char)data); //send LSB
|
||||||
|
sendchar((char)(data >> 8)); //send MSB
|
||||||
|
address += 2; // Select next word in memory
|
||||||
|
size -= 2; // Subtract two bytes from number of bytes to read
|
||||||
|
} while (size); // Repeat until all block has been read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
405
makefile
Normal file
405
makefile
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al.
|
||||||
|
# Released to the Public Domain
|
||||||
|
# Please read the make user manual!
|
||||||
|
#
|
||||||
|
# Additional material for this makefile was submitted by:
|
||||||
|
# Tim Henigan
|
||||||
|
# Peter Fleury
|
||||||
|
# Reiner Patommel
|
||||||
|
# Sander Pool
|
||||||
|
# Frederik Rouleau
|
||||||
|
# Markus Pfaff
|
||||||
|
#
|
||||||
|
# On command line:
|
||||||
|
#
|
||||||
|
# make all = Make software.
|
||||||
|
#
|
||||||
|
# make clean = Clean out built project files.
|
||||||
|
#
|
||||||
|
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
|
||||||
|
#
|
||||||
|
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
|
||||||
|
# 4.07 or greater).
|
||||||
|
#
|
||||||
|
# make program = Download the hex file to the device, using avrdude. Please
|
||||||
|
# customize the avrdude settings below first!
|
||||||
|
#
|
||||||
|
# make filename.s = Just compile filename.c into the assembler code only
|
||||||
|
#
|
||||||
|
# To rebuild project do "make clean" then "make all".
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
# MCU name
|
||||||
|
MCU = atmega16
|
||||||
|
|
||||||
|
# Output format. (can be srec, ihex, binary)
|
||||||
|
FORMAT = ihex
|
||||||
|
|
||||||
|
# Target file name (without extension).
|
||||||
|
TARGET = main
|
||||||
|
|
||||||
|
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
|
||||||
|
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||||
|
OPT = s
|
||||||
|
|
||||||
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
|
SRC = $(TARGET).c
|
||||||
|
|
||||||
|
# If there is more than one source file, append them above, or modify and
|
||||||
|
# uncomment the following:
|
||||||
|
# mt: the file test.c can be omitted (remove #inc test.h and test() in main.c)
|
||||||
|
SRC += lowlevel.c \
|
||||||
|
uart.c
|
||||||
|
|
||||||
|
|
||||||
|
# You can also wrap lines by appending a backslash to the end of the line:
|
||||||
|
#SRC += baz.c \
|
||||||
|
#xyzzy.c
|
||||||
|
|
||||||
|
# List Assembler source files here.
|
||||||
|
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||||
|
# will not be considered source files but generated files (assembler
|
||||||
|
# output from the compiler), and will be deleted upon "make clean"!
|
||||||
|
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||||
|
# it will preserve the spelling of the filenames, and gcc itself does
|
||||||
|
# care about how the name is spelled on its command-line.
|
||||||
|
ASRC =
|
||||||
|
|
||||||
|
|
||||||
|
# List any extra directories to look for include files here.
|
||||||
|
# Each directory must be seperated by a space.
|
||||||
|
EXTRAINCDIRS =
|
||||||
|
|
||||||
|
|
||||||
|
# Optional compiler flags.
|
||||||
|
# -g: generate debugging information (for GDB, or for COFF conversion)
|
||||||
|
# -O*: optimization level
|
||||||
|
# -f...: tuning, see gcc manual and avr-libc documentation
|
||||||
|
# -Wall...: warning level
|
||||||
|
# -Wa,...: tell GCC to pass this to the assembler.
|
||||||
|
# -ahlms: create assembler listing
|
||||||
|
CFLAGS = -g -O$(OPT) \
|
||||||
|
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
|
||||||
|
-Wall -Wstrict-prototypes \
|
||||||
|
-Wa,-adhlns=$(<:.c=.lst) \
|
||||||
|
$(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||||
|
|
||||||
|
|
||||||
|
# Set a "language standard" compiler flag.
|
||||||
|
# Unremark just one line below to set the language standard to use.
|
||||||
|
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
|
||||||
|
#CFLAGS += -std=c89
|
||||||
|
#CFLAGS += -std=gnu89
|
||||||
|
#CFLAGS += -std=c99
|
||||||
|
CFLAGS += -std=gnu99
|
||||||
|
|
||||||
|
|
||||||
|
# Optional assembler flags.
|
||||||
|
# -Wa,...: tell GCC to pass this to the assembler.
|
||||||
|
# -ahlms: create listing
|
||||||
|
# -gstabs: have the assembler create line number information; note that
|
||||||
|
# for use in COFF files, additional information about filenames
|
||||||
|
# and function names needs to be present in the assembler source
|
||||||
|
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||||
|
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Optional linker flags.
|
||||||
|
# -Wl,...: tell GCC to pass this to linker.
|
||||||
|
# -Map: create map file
|
||||||
|
# --cref: add cross reference to map file
|
||||||
|
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||||
|
|
||||||
|
# Additional libraries
|
||||||
|
|
||||||
|
# Minimalistic printf version
|
||||||
|
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
|
||||||
|
|
||||||
|
# Floating point printf version (requires -lm below)
|
||||||
|
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
|
||||||
|
|
||||||
|
# -lm = math library
|
||||||
|
LDFLAGS += -lm
|
||||||
|
|
||||||
|
################## BOOTLOADER ######################
|
||||||
|
# mt: Boot loader support. So far not done with a separate section
|
||||||
|
# to get the interrupt vector into the bootloader area.
|
||||||
|
# bootloader address in datasheet and stk500 is given as
|
||||||
|
# "word", gcc toolchain needs "byte"-address (here: 0x1C00*2)
|
||||||
|
MT_BOOTLOADER_ADDRESS = 3800
|
||||||
|
LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
|
||||||
|
|
||||||
|
# Programming support using avrdude. Settings and variables.
|
||||||
|
|
||||||
|
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||||
|
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||||
|
#
|
||||||
|
# Type: avrdude -c ?
|
||||||
|
# to get a full listing.
|
||||||
|
#
|
||||||
|
AVRDUDE_PROGRAMMER = stk500
|
||||||
|
|
||||||
|
|
||||||
|
AVRDUDE_PORT = com1 # programmer connected to serial device
|
||||||
|
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
|
||||||
|
|
||||||
|
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||||
|
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||||
|
|
||||||
|
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||||
|
|
||||||
|
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||||
|
# Note that this counter needs to be initialized first using -Yn,
|
||||||
|
# see avrdude manual.
|
||||||
|
#AVRDUDE_ERASE += -y
|
||||||
|
|
||||||
|
# Uncomment the following if you do /not/ wish a verification to be
|
||||||
|
# performed after programming the device.
|
||||||
|
#AVRDUDE_FLAGS += -V
|
||||||
|
|
||||||
|
# Increase verbosity level. Please use this when submitting bug
|
||||||
|
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||||
|
# to submit bug reports.
|
||||||
|
#AVRDUDE_FLAGS += -v -v
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Define directories, if needed.
|
||||||
|
DIRAVR = c:/winavr
|
||||||
|
DIRAVRBIN = $(DIRAVR)/bin
|
||||||
|
DIRAVRUTILS = $(DIRAVR)/utils/bin
|
||||||
|
DIRINC = .
|
||||||
|
DIRLIB = $(DIRAVR)/avr/lib
|
||||||
|
|
||||||
|
|
||||||
|
# Define programs and commands.
|
||||||
|
SHELL = sh
|
||||||
|
|
||||||
|
CC = avr-gcc
|
||||||
|
|
||||||
|
OBJCOPY = avr-objcopy
|
||||||
|
OBJDUMP = avr-objdump
|
||||||
|
SIZE = avr-size
|
||||||
|
|
||||||
|
|
||||||
|
# Programming support using avrdude.
|
||||||
|
AVRDUDE = avrdude
|
||||||
|
|
||||||
|
|
||||||
|
REMOVE = rm -f
|
||||||
|
COPY = cp
|
||||||
|
|
||||||
|
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||||
|
#mt - use hexadezimal output-fromat // org: ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||||
|
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
|
||||||
|
|
||||||
|
|
||||||
|
# Define Messages
|
||||||
|
# English
|
||||||
|
MSG_ERRORS_NONE = Errors: none
|
||||||
|
MSG_BEGIN = -------- begin --------
|
||||||
|
MSG_END = -------- end --------
|
||||||
|
MSG_SIZE_BEFORE = Size before:
|
||||||
|
MSG_SIZE_AFTER = Size after:
|
||||||
|
MSG_COFF = Converting to AVR COFF:
|
||||||
|
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||||
|
MSG_FLASH = Creating load file for Flash:
|
||||||
|
MSG_EEPROM = Creating load file for EEPROM:
|
||||||
|
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||||
|
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||||
|
MSG_LINKING = Linking:
|
||||||
|
MSG_COMPILING = Compiling:
|
||||||
|
MSG_ASSEMBLING = Assembling:
|
||||||
|
MSG_CLEANING = Cleaning project:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Define all object files.
|
||||||
|
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
|
||||||
|
|
||||||
|
# Define all listing files.
|
||||||
|
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
|
||||||
|
|
||||||
|
# Combine all necessary flags and optional flags.
|
||||||
|
# Add target processor to flags.
|
||||||
|
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
|
||||||
|
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Default target.
|
||||||
|
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
|
||||||
|
$(TARGET).lss $(TARGET).sym sizeafter finished end
|
||||||
|
|
||||||
|
|
||||||
|
# Eye candy.
|
||||||
|
# AVR Studio 3.x does not check make's exit code but relies on
|
||||||
|
# the following magic strings to be generated by the compile job.
|
||||||
|
begin:
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_BEGIN)
|
||||||
|
|
||||||
|
finished:
|
||||||
|
@echo $(MSG_ERRORS_NONE)
|
||||||
|
|
||||||
|
end:
|
||||||
|
@echo $(MSG_END)
|
||||||
|
@echo
|
||||||
|
|
||||||
|
|
||||||
|
# Display size of file.
|
||||||
|
sizebefore:
|
||||||
|
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
|
||||||
|
|
||||||
|
sizeafter:
|
||||||
|
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Display compiler version information.
|
||||||
|
gccversion :
|
||||||
|
@$(CC) --version
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Convert ELF to COFF for use in debugging / simulating in
|
||||||
|
# AVR Studio or VMLAB.
|
||||||
|
COFFCONVERT=$(OBJCOPY) --debugging \
|
||||||
|
--change-section-address .data-0x800000 \
|
||||||
|
--change-section-address .bss-0x800000 \
|
||||||
|
--change-section-address .noinit-0x800000 \
|
||||||
|
--change-section-address .eeprom-0x810000
|
||||||
|
|
||||||
|
|
||||||
|
coff: $(TARGET).elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_COFF) $(TARGET).cof
|
||||||
|
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||||
|
|
||||||
|
|
||||||
|
extcoff: $(TARGET).elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||||
|
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Program the device.
|
||||||
|
program: $(TARGET).hex $(TARGET).eep
|
||||||
|
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Create final output files (.hex, .eep) from ELF output file.
|
||||||
|
%.hex: %.elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_FLASH) $@
|
||||||
|
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||||
|
|
||||||
|
%.eep: %.elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_EEPROM) $@
|
||||||
|
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||||
|
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||||
|
|
||||||
|
# Create extended listing file from ELF output file.
|
||||||
|
%.lss: %.elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_EXTENDED_LISTING) $@
|
||||||
|
$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
# Create a symbol table from ELF output file.
|
||||||
|
%.sym: %.elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_SYMBOL_TABLE) $@
|
||||||
|
avr-nm -n $< > $@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Link: create ELF output file from object files.
|
||||||
|
.SECONDARY : $(TARGET).elf
|
||||||
|
.PRECIOUS : $(OBJ)
|
||||||
|
%.elf: $(OBJ)
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_LINKING) $@
|
||||||
|
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
# Compile: create object files from C source files.
|
||||||
|
%.o : %.c
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_COMPILING) $<
|
||||||
|
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
# Compile: create assembler files from C source files.
|
||||||
|
%.s : %.c
|
||||||
|
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
# Assemble: create object files from assembler source files.
|
||||||
|
%.o : %.S
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_ASSEMBLING) $<
|
||||||
|
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Target: clean project.
|
||||||
|
clean: begin clean_list finished end
|
||||||
|
|
||||||
|
clean_list :
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_CLEANING)
|
||||||
|
$(REMOVE) $(TARGET).hex
|
||||||
|
$(REMOVE) $(TARGET).eep
|
||||||
|
$(REMOVE) $(TARGET).obj
|
||||||
|
$(REMOVE) $(TARGET).cof
|
||||||
|
$(REMOVE) $(TARGET).elf
|
||||||
|
$(REMOVE) $(TARGET).map
|
||||||
|
$(REMOVE) $(TARGET).obj
|
||||||
|
$(REMOVE) $(TARGET).a90
|
||||||
|
$(REMOVE) $(TARGET).sym
|
||||||
|
$(REMOVE) $(TARGET).lnk
|
||||||
|
$(REMOVE) $(TARGET).lss
|
||||||
|
$(REMOVE) $(OBJ)
|
||||||
|
$(REMOVE) $(LST)
|
||||||
|
$(REMOVE) $(SRC:.c=.s)
|
||||||
|
$(REMOVE) $(SRC:.c=.d)
|
||||||
|
|
||||||
|
|
||||||
|
# Automatically generate C source code dependencies.
|
||||||
|
# (Code originally taken from the GNU make user manual and modified
|
||||||
|
# (See README.txt Credits).)
|
||||||
|
#
|
||||||
|
# Note that this will work with sh (bash) and sed that is shipped with WinAVR
|
||||||
|
# (see the SHELL variable defined above).
|
||||||
|
# This may not work with other shells or other seds.
|
||||||
|
#
|
||||||
|
%.d: %.c
|
||||||
|
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
|
||||||
|
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
|
||||||
|
[ -s $@ ] || rm -f $@
|
||||||
|
|
||||||
|
|
||||||
|
# Remove the '-' if you want to see the dependency files generated.
|
||||||
|
-include $(SRC:.c=.d)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Listing of phony targets.
|
||||||
|
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
|
||||||
|
clean clean_list program
|
||||||
|
|
119
readme.txt
Normal file
119
readme.txt
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
|
||||||
|
======================================================
|
||||||
|
|
||||||
|
ATMEL AVR UART Bootloader for AVR-GCC/avr-libc
|
||||||
|
based on the AVR Butterfly bootloader code
|
||||||
|
|
||||||
|
by Martin Thomas, Kaiserslautern, Germany
|
||||||
|
mthomas@rhrk.uni-kl.de
|
||||||
|
eversmith@heizung-thomas.de
|
||||||
|
|
||||||
|
This is an adapted version which has been tested
|
||||||
|
with the ATmega16 but should work with the ATmega8,
|
||||||
|
ATmega169 and ATmega32. The bootloader uses block/
|
||||||
|
page write and is fast.
|
||||||
|
|
||||||
|
======================================================
|
||||||
|
|
||||||
|
|
||||||
|
24. Mar 2004 - Version 0.2
|
||||||
|
|
||||||
|
During the development of a data-logger application
|
||||||
|
with the AVR-Butterfly there was a need to make
|
||||||
|
some changes in the bootloader. The same problem
|
||||||
|
again: no IAR compiler. The same way to solve the
|
||||||
|
problem: a port of the code to avr-gcc/avr-libc.
|
||||||
|
So this code is based on the ATMEL Butterfly
|
||||||
|
bootloader source code Rev 0.2 for IAR.
|
||||||
|
|
||||||
|
The bootloader-port for the Butterfly which mimics
|
||||||
|
the complete functionality of the original
|
||||||
|
BF-bootloader is availabe at:
|
||||||
|
www.siwawi.arubi.uni-kl.de/avr_projects
|
||||||
|
|
||||||
|
Atmel used a separate "lib" written in "pure"
|
||||||
|
assembly to access the low-level functions
|
||||||
|
for flash and eeprom read/write. Well, so far I
|
||||||
|
don't know how to use "mixed language sources"
|
||||||
|
with the avr-gcc toolchain, so the low-level
|
||||||
|
routines have been implemented as inline assembler.
|
||||||
|
The avr-libc boot.h module written by Eric
|
||||||
|
Weddington served as a template Three of the four
|
||||||
|
low-level routines found in lowlevel.c come from
|
||||||
|
boot.h with minimal changes. The read routine has
|
||||||
|
been developed based on the ATMEL assembler code.
|
||||||
|
|
||||||
|
Ignore the fuse and lock-bit readout. Read and Set is
|
||||||
|
not enabled (TODO).
|
||||||
|
|
||||||
|
|
||||||
|
--------------- Installation -----------------
|
||||||
|
|
||||||
|
- Change the MCU type in the makefile (so far
|
||||||
|
ATmega16 has been tested, ATmega169, ATmega8
|
||||||
|
and ATmega32 should be o.k. too.
|
||||||
|
|
||||||
|
- Change the boot(loader)-size in main.c, this
|
||||||
|
bootloader is larger than 512 words (1024 bytes),
|
||||||
|
so select at least _B1024!
|
||||||
|
|
||||||
|
- Change the XTAL in main.c to the clock-frequency
|
||||||
|
of your board (keep BAUDRATE at 19200). See
|
||||||
|
the datasheet for frequencies with minimum
|
||||||
|
error at 19200bps and select Crystal/Oscillator
|
||||||
|
to get minimum errors.
|
||||||
|
|
||||||
|
- Change the start-condition in main.c. Default
|
||||||
|
is: enter bootloader if Pin A7 is connected to
|
||||||
|
GND during reset/startup
|
||||||
|
|
||||||
|
- Edit the value MT_BOOTLOADER_ADDRESS in the
|
||||||
|
makefile according to the selected bootloader
|
||||||
|
size. Keep in mind that this value has to be
|
||||||
|
given in bytes (not words) in the linker options.
|
||||||
|
|
||||||
|
i.e. ATMega16, boot-size 1024 words, see
|
||||||
|
datasheet and find "Boot Reset Adress" for
|
||||||
|
"Boot Size" 1024 words is 1C00. 1C00 is given
|
||||||
|
in words, so set MT_BOOTLOADER_ADDRESS to
|
||||||
|
3800 (=2*1C00)
|
||||||
|
|
||||||
|
- Please use at least avr-gcc 3.3.1/avr-libc 1.0
|
||||||
|
or WINAVR Sept. 2003 or later to compile and link
|
||||||
|
the bootloader.
|
||||||
|
|
||||||
|
- upload the hex-File to the AVR (STK500, STK200, SP12
|
||||||
|
etc.)
|
||||||
|
|
||||||
|
- program the "Boot Flash section size" (BOOTSZ fuses)
|
||||||
|
according to the boot-size selected in main.c
|
||||||
|
i.e. BOOTSZ=00 for boot-size 1024 words on ATmega16
|
||||||
|
|
||||||
|
- enable the BOOT Reset Vector (BOOTTRST=0)
|
||||||
|
|
||||||
|
- Set the lock bits to protect the bootloader from
|
||||||
|
SPM-writes (Boot Loader Protection Mode 2 in STK500-
|
||||||
|
plugin)
|
||||||
|
|
||||||
|
- Connect the AVR UART Pins via level-shifter/inverter
|
||||||
|
(i.e. MAX232) to you PCs Com-Port.
|
||||||
|
|
||||||
|
- Reset the AVR while fullfilling the bootloader start-
|
||||||
|
condition. Which means connect PA7 to GND in the default
|
||||||
|
config during reste/power-cycle. Keep the connection
|
||||||
|
or hold the key down until you see the AVRPROG dialog!
|
||||||
|
|
||||||
|
- Start AVRPROG (AVRStuido/Tools or stand-alone) -
|
||||||
|
keep PA7 grounded!
|
||||||
|
|
||||||
|
- AVRPROG will detect the bootloader, you may release
|
||||||
|
PA7 now
|
||||||
|
|
||||||
|
- see AVRStuido online-help for more information how
|
||||||
|
to use AVRPROG
|
||||||
|
|
||||||
|
- make sure to EXIT from AVRPROG (button) to start
|
||||||
|
your main-application (or toogle power/reset)
|
||||||
|
|
||||||
|
good luck, feedback welcome.
|
||||||
|
Martin
|
151
uart.c
Normal file
151
uart.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
/* most of the definitions borrowed from Peter Fleury's UART-Library
|
||||||
|
extende for control-register C and ATmega169 */
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
|
||||||
|
|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
|
||||||
|
|| defined(__AVR_ATmega323__)
|
||||||
|
/* ATMega with one USART */
|
||||||
|
#define ATMEGA_USART
|
||||||
|
#define UART0_UBRR_HIGH UBRRH
|
||||||
|
#define UART0_UBRR_LOW UBRRL
|
||||||
|
#define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
||||||
|
#define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
||||||
|
#define UART0_STATUS UCSRA
|
||||||
|
#define UART0_CONTROL UCSRB
|
||||||
|
#define UART0_DATA UDR
|
||||||
|
#define UART0_UDRIE UDRIE
|
||||||
|
#elif defined(__AVR_ATmega162__)
|
||||||
|
/* ATMega with two USART */
|
||||||
|
#define ATMEGA_USART0
|
||||||
|
#define ATMEGA_USART1
|
||||||
|
#define UART0_UBRR_HIGH UBRR0H
|
||||||
|
#define UART0_UBRR_LOW UBRR0L
|
||||||
|
#define UART1_UBRR_HIGH UBRR1H
|
||||||
|
#define UART1_UBRR_LOW UBRR1L
|
||||||
|
#define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
|
||||||
|
#define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
|
||||||
|
#define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
|
||||||
|
#define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
|
||||||
|
#define UART0_STATUS UCSR0A
|
||||||
|
#define UART0_CONTROL UCSR0B
|
||||||
|
#define UART0_CONTROL2 UCSR0C
|
||||||
|
#define UART0_DATA UDR0
|
||||||
|
#define UART0_UDRIE UDRIE0
|
||||||
|
#define UART1_STATUS UCSR1A
|
||||||
|
#define UART1_CONTROL UCSR1B
|
||||||
|
#define UART1_CONTROL2 UCSR1C
|
||||||
|
#define UART1_DATA UDR1
|
||||||
|
#define UART1_UDRIE UDRIE1
|
||||||
|
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
|
||||||
|
/* ATMega with two USART */
|
||||||
|
#define ATMEGA_USART0
|
||||||
|
#define ATMEGA_USART1
|
||||||
|
#define UART0_UBRR_HIGH UBRR0H
|
||||||
|
#define UART0_UBRR_LOW UBRR0L
|
||||||
|
#define UART1_UBRR_HIGH UBRR1H
|
||||||
|
#define UART1_UBRR_LOW UBRR1L
|
||||||
|
#define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV
|
||||||
|
#define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV
|
||||||
|
#define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA
|
||||||
|
#define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA
|
||||||
|
#define UART0_STATUS UCSR0A
|
||||||
|
#define UART0_CONTROL UCSR0B
|
||||||
|
#define UART0_CONTROL2 UCSR0C
|
||||||
|
#define UART0_DATA UDR0
|
||||||
|
#define UART0_UDRIE UDRIE0
|
||||||
|
#define UART1_STATUS UCSR1A
|
||||||
|
#define UART1_CONTROL UCSR1B
|
||||||
|
#define UART1_CONTROL2 UCSR1C
|
||||||
|
#define UART1_DATA UDR1
|
||||||
|
#define UART1_UDRIE UDRIE1
|
||||||
|
#elif defined(__AVR_ATmega169__)
|
||||||
|
#define ATMEGA_USART
|
||||||
|
#define UART0_UBRR_HIGH UBRR0H
|
||||||
|
#define UART0_UBRR_LOW UBRR0L
|
||||||
|
// TODO #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
||||||
|
// TODO #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
||||||
|
#define UART0_STATUS UCSR0A
|
||||||
|
#define UART0_CONTROL UCSR0B
|
||||||
|
#define UART0_CONTROL2 UCSR0C
|
||||||
|
#define UART0_DATA UDR0
|
||||||
|
#define UART0_DOUBLEAVAIL
|
||||||
|
// TODO #define UART0_UDRIE UDRIE
|
||||||
|
#else
|
||||||
|
#error "Processor type not supported in uart.c !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void USART_Init(unsigned int baudrate, unsigned char doublespeed)
|
||||||
|
{
|
||||||
|
// Set baud rate
|
||||||
|
UART0_UBRR_HIGH = (unsigned char)(baudrate>>8);
|
||||||
|
UART0_UBRR_LOW = (unsigned char)baudrate;
|
||||||
|
|
||||||
|
// Enable 2x speed - TODO adopt to all uCs
|
||||||
|
#ifdef UART0_DOUBLEAVAIL
|
||||||
|
if (doublespeed) UCSR0A = (1<<U2X0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (ATMEGA_USART)
|
||||||
|
/* Enable USART receiver and transmitter and disable interrupts */
|
||||||
|
UART0_CONTROL = (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<UDRIE);
|
||||||
|
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
||||||
|
#ifdef URSEL
|
||||||
|
UCSRC = (1<<URSEL)|(3<<UCSZ0);
|
||||||
|
#else
|
||||||
|
UCSRC = (3<<UCSZ0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined (ATMEGA_USART0 )
|
||||||
|
/* Enable USART receiver and transmitter and disable interrupts */
|
||||||
|
UART0_CONTROL = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);
|
||||||
|
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
||||||
|
#ifdef URSEL0
|
||||||
|
UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
|
||||||
|
#else
|
||||||
|
UCSR0C = (3<<UCSZ00);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendchar(char data)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
UART0_DATA = data;
|
||||||
|
|
||||||
|
if(SREG & 0x80)
|
||||||
|
{
|
||||||
|
while ( !(UART0_STATUS&0x40) && (i<10000) )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while( !(UART0_STATUS&0x40) );
|
||||||
|
|
||||||
|
UART0_STATUS=UART0_STATUS|0x40; //delete TXCflag
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char recchar(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if(SREG & 0x80)
|
||||||
|
{
|
||||||
|
// while (!(UART0_STATUS & (1<<RXC0)) && (i<10000))
|
||||||
|
while (!(UART0_STATUS & 0x80) && (i<10000))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// while(!(UART0_STATUS & (1<<RXC0)));
|
||||||
|
while(!(UART0_STATUS & 0x80));
|
||||||
|
|
||||||
|
return UART0_DATA ;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user