4 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef __AVR_MCU_SECTION_H__
23 #define __AVR_MCU_SECTION_H__
26 * This header is used to pass "parameters" to the programmer or the simulator,
27 * it tags the ELF file with a section that contains parameters about the physical
28 * AVR this was compiled for, including the speed, model, and signature bytes.
30 * A programmer software can read this and verify fuses values for example, and a
31 * simulator can instanciate the proper "model" of AVR, the speed and so on without
32 * command line parameters.
36 * #include "avr_mcu_section.h"
37 * AVR_MCU(F_CPU, "atmega88");
46 AVR_MMCU_TAG_FREQUENCY,
50 AVR_MMCU_TAG_SIGNATURE,
51 AVR_MMCU_TAG_SIMAVR_COMMAND,
52 AVR_MMCU_TAG_VCD_FILENAME,
53 AVR_MMCU_TAG_VCD_PERIOD,
54 AVR_MMCU_TAG_VCD_TRACE,
59 SIMAVR_CMD_VCD_START_TRACE,
60 SIMAVR_CMD_VCD_STOP_TRACE,
61 SIMAVR_CMD_UART_LOOPBACK,
66 #define _MMCU_ __attribute__((section(".mmcu")))
67 struct avr_mmcu_long_t {
71 } __attribute__((__packed__));
73 struct avr_mmcu_string_t {
77 } __attribute__((__packed__));
79 struct avr_mmcu_addr_t {
83 } __attribute__((__packed__));
85 struct avr_mmcu_vcd_trace_t {
91 } __attribute__((__packed__));
93 #define AVR_MCU_STRING(_tag, _str) \
94 const struct avr_mmcu_string_t _##_tag _MMCU_ = {\
100 #define AVR_MCU_LONG(_tag, _val) \
101 const struct avr_mmcu_long_t _##_tag _MMCU_ = {\
103 .len = sizeof(uint32_t),\
107 #define AVR_MCU_BYTE(_tag, _val) \
108 const uint8_t _##_tag _MMCU_ = { _tag, 1, _val }
110 #define AVR_MCU_VCD_SYMBOL(_name) \
111 .tag = AVR_MMCU_TAG_VCD_TRACE, \
112 .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2 + sizeof(_name),\
115 // specified the name and wanted period (usec) for a VCD file
116 // thid is not mandatory, a default one will be created if
117 // symbols are declared themselves
118 #define AVR_MCU_VCD_FILE(_name, _period) \
119 AVR_MCU_STRING(AVR_MMCU_TAG_VCD_FILENAME, _name);\
120 AVR_MCU_LONG(AVR_MMCU_TAG_VCD_PERIOD, _period)
122 // It is possible to send "commands" to simavr from the
123 // firmware itself. For this to work you need to specify
124 // an IO register that is to be used for a write-only
125 // bridge. A favourite is one of the usual "GPIO register"
126 // that most (all ?) AVR have
127 #define AVR_MCU_SIMAVR_COMMAND(_register) \
128 const struct avr_mmcu_addr_t _simavr_command_register _MMCU_ = {\
129 .tag = AVR_MMCU_TAG_SIMAVR_COMMAND,\
130 .len = sizeof(void *),\
131 .what = (void*)_register, \
135 * This the has to be used if you want to add other tags to the .mmcu section
136 * the _mmcu symbol is used as an anchor to make sure it stays linked in.
138 #define AVR_MCU(_speed, _name) \
139 const uint8_t _mmcu[2] _MMCU_ = { AVR_MMCU_TAG, 0 }; \
140 AVR_MCU_STRING(AVR_MMCU_TAG_NAME, _name);\
141 AVR_MCU_LONG(AVR_MMCU_TAG_FREQUENCY, _speed)