wiki:HowToAddNewAvrMicrocontroller

How to add a new AVR microcontroller

Each microcontroller in mcusim can be described using a specially created header file to declare MCU-specific parameters (reset address, number of registers, etc) and a source file to implement MCU-specific functions. These functions aren't generally portable between different AVR models and used to initialize MCU, configure it according to the fuse bytes and lock bits provided by a user, tick timers, provide IRQs and so on. Adding support for a new model means preparing these two files and adjusting a build system to include them.

Let's try to dig into the files which define ATmega8A microcontroller in mcusim.

Header file

mcusim/avr/sim/simm8a.h starts from including headers declared in mcusim/avr/io.h:

#define __AVR_ATmega8A__ 1
#include "mcusim/avr/io.h"

io.h was copied from avr-libc project and contains device-specific I/O definitions for many AVR models. This is why we've to select an AVR model by defining __AVR_ATmega8A__ macro. It's highly unlikely for mcusim to contain a required header from avr-libc and you'll have to copy and add it manually to mcusim/avr and adjust io.h to include a correct one.

The next part of the file is a section with default parameters (in addition to the io.h definitions) and MCU-specific functions:

#define MCU_NAME        "ATmega8A"

#define RESET_PC        0x0000  /* Reset vector address, in bytes */
#define IVT_ADDR        0x0002  /* Interrupt vectors address, in bytes */
#define PC_BITS         12      /* PC bit capacity */
#define LBITS_DEFAULT   0x3F    /* Default lock bits */

#define CLK_SOURCE      AVR_INT_CAL_RC_CLK /* Calibrated Internal RC */
#define CLK_FREQ        1000000 /* Oscillator frequency, in Hz */

#define GP_REGS         32      /* GP registers (r0, r1, etc.) */
#define IO_REGS         64      /* I/O registers (PORTD, SREG, etc.) */

#define BLS_START       0x1800  /* First address in BLS, in bytes */
#define BLS_END         0x1FFF  /* Last address in BLS, in bytes */
#define BLS_SIZE        2048    /* BLS size, in bytes */

#define SET_FUSE_F      MSIM_M8ASetFuse
#define SET_LOCK_F      MSIM_M8ASetLock
#define TICK_TIMERS_F   MSIM_M8ATickTimers
#define PROVIDE_IRQS_F  MSIM_M8AProvideIRQs

int MSIM_M8ASetFuse(void *mcu, unsigned int fuse_n, unsigned char fuse_v);
int MSIM_M8ASetLock(void *mcu, unsigned char lock_v);
int MSIM_M8ATickTimers(void *mcu);
int MSIM_M8AProvideIRQs(void *mcu);

#define SREG            _SFR_IO8(0x3F)
#define SPH             _SFR_IO8(0x3E)
#define SPL             _SFR_IO8(0x3D)

This is a full list of available parameters (from MCU agnostic initialization function)

Parameter Type Optional Default value Description
MCU_NAMEstring-N/AHuman-readable name of a microcontroller
PC_BITSinteger-N/ANumber of bits in program counter (PC) register
RESET_PCinteger-N/AReset vector address, in bytes
XMEGAbooleanyesfalseFlag to mark XMEGA AVR core
REDUCED_COREbooleanyesfalseFlag to mark reduced AVR core
GP_REGSinteger-N/ANumber of general purpose AVR registers (R0, R1, ...)
IO_REGSinteger-N/ANumber of I/O registers (PORTD, SREG, etc)
SREGinteger-N/AOffset to the status register in data memory
SPHinteger-N/AOffset to the stack pointer (high byte) in data memory
SPLinteger-N/AOffset to the stack pointer (low byte) in data memory
EFUSE_DEFAULTintegeryesprovided(1)Extended fuse byte value (this value is usually defined in the MCU-specific header and can be overwritten)
HFUSE_DEFAULTintegeryesprovidedHigh fuse byte value (this value is usually defined in the MCU-specific header and can be overwritten)
LFUSE_DEFAULTinteger-providedLow fuse byte value (this value is usually defined in the MCU-specific header and can be overwritten)
LBITS_DEFAULTinteger-N/ADefault lock bits value
SET_FUSE_Ffunction pointeryesN/APointer to the MCU-specific function to configure microcontroller according to the given fuse byte (function signature matters(2))
SET_LOCK_Ffunction pointeryesN/APointer to the MCU-specific function to configure microcontroller according to the given lock byte
TICK_TIMERS_Ffunction pointeryesN/APointer to the MCU-specific function to tick timers
PROVIDE_IRQS_Ffunction pointeryesN/APointer to the MCU-specific function to provide interrupt requests
CLK_SOURCEenum-N/AType of the MCU clock source(3)
CLK_FREQinteger-N/ADefault frequency of the selected clock source, in Hz
EINDintegeryesN/AOffset to the EIND register in data memory
RAMPZintegeryesN/AOffset to the RAMPZ register in data memory
RAMPYintegeryesN/AOffset to the RAMPY register in data memory
RAMPXintegeryesN/AOffset to the RAMPX register in data memory
RAMPDintegeryesN/AOffset to the RAMPD register in data memory
BLS_STARTintegeryes0First address in bootloader section, in bytes
BLS_ENDintegeryes0Last address in bootloader section, in bytes
BLS_SIZEintegeryes0Size of the bootloader section, in bytes

Notes:

  1. Default value provided by the MCU-specific header
  2. Signatures of the MCU-specific functions should match types declared in mcusim/avr/sim/sim.h
  3. Possible values are defined in mcusim/avr/sim/sim.h

Feel free to modify MCU-agnostic initialization function to add new parameters and fix bugs. However, keep its agnostic nature in mind - this function should work for all types of the AVR microcontrollers.

The last part of the file is a header with I/O registers which can be included into value-change dump (VCD) file:

#include "mcusim/avr/sim/vcd_regs.h"

You may just copy and paste this line as is, without any modifications. However, its place matters - put it in the end of the header file you're working on.

Source file

...

Last modified 5 weeks ago Last modified on Oct 10, 2018, 11:20:30 AM