This is the engineering reference for the model: what it implements, register by register, for people writing firmware against it. For using the board in the editor, start with The Arduino Uno R4 Minima and the board page.
Arduino Uno R4 Minima board contract (Phase 9)
The Arduino Uno R4 Minima is a Renesas RA4M1 (a Cortex-M4 at 48 MHz) in an Uno's shape. One kernel component (unor4 in crates/parts) wraps an RA4M1 SoC model (crates/unor4) on the same ARMv7-M core as the Blue Pill and the Black Pill (crates/cortexm-core). The core is shared; the chip around it is not, and nothing about the pins is.
The catalog type is unor4. This document is the contract, and it wins over any comment in the code.
Read section 7 first if you are taking a build from here to real silicon. This model is smaller than the RA4M1, and several of its addresses are marked "believed, not verified": section 7 says which, and what is absent altogether. Nothing here is guessed at quietly.
Why this is not a Blue Pill with different numbers
An RA is a different world from an STM32, and the differences are the ones a sketch trips over:
- A pin is one register.
PmnPFSis a 32-bit word per pin holding direction, the output latch, the pull-up, open drain, the analog switch, "a peripheral owns this pin now" and which peripheral. There is noMODER, noCRL/CRH, noPUPDRand noAFR. - That register is write-protected.
PWPR.B0WIhas to go clear andPWPR.PFSWEset before anyPmnPFSwrite lands. A program that forgets findsdigitalWriteworking andpinModedoing nothing at all. This model enforces it and counts what it threw away. - A peripheral has no clock until you say so. Every bit in the module stop registers resets to "stopped". SCI, GPT, ADC14 and USB are all unreachable (reads return zero) until
MSTPCRB/MSTPCRDare written. - There is a pull-up and no pull-down.
INPUT_PULLDOWNgets a plain floating input here, and says so. Serialis USB, not a UART. The UART on D0 and D1 isSerial1. On an Uno the two are one thing.- The converter is fourteen bits.
analogReadstill returns ten, because that is what an Arduino sketch expects;analogReadResolutionasks for the rest. - The flash is at zero. No alias, no BOOT pin, and an option-setting word at
0x400that a real part reads out of reset. - The built-in LED is active high, like an Uno's and unlike a Blue Pill's.
1. Board pins (catalog order)
Hole for hole, an Uno R3 header, which is what lets an R4 take an Uno shield. The board is 68.6 x 53.3 mm.
Top row, left to right (14 holes): SCL, SDA, AREF, GND, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.
Bottom row, left to right (13 holes): IOREF, RESET, 3V3, 5V, GNDb, GNDc, VIN, A0, A1, A2, A3, A4, A5.
31 pins. Duplicated names carry a letter because catalog pin names are unique.
SCL and SDA beside AREF are the same two pieces of metal as A5 and A4: one trace, two holes, as on an Uno. Driving either end drives both.
The RA4M1 pin behind each hole:
| hole | pad | also |
|---|---|---|
0 |
P301 | RXD2, Serial1 receive |
1 |
P302 | TXD2, Serial1 transmit |
2 |
P104 | |
3 |
P105 | PWM |
4 |
P106 | |
5 |
P107 | PWM |
6 |
P111 | PWM |
7 |
P112 | |
8 |
P303 | |
9 |
P304 | PWM |
10 |
P103 | PWM, SS |
11 |
P411 | PWM, MOSI |
12 |
P410 | MISO |
13 |
P102 | SCK, LED_BUILTIN |
A0 |
P014 | AN009 |
A1 |
P000 | AN000 |
A2 |
P001 | AN001 |
A3 |
P002 | AN002 |
A4 |
P101 | AN021, SDA |
A5 |
P100 | AN022, SCL |
A4's and A5's channel numbers are unverified (section 7). The other four are not.
Electrical: every I/O drives push-pull at 5 V through R_STRONG, sits high-Z, or pulls up through 35 k. There is no internal pull-down. An input reads high at 2.5 V; a floating or contended net reads 0. 5V and IOREF drive 5 V at R_SUPPLY, 3V3 drives 3.3 V, the three grounds drive 0 V. RESET carries a 10 k pull-up to 5 V, and pulling it below 2.5 V holds the core in reset. VIN and AREF are inputs the model reads and does nothing with.
Pin 13 carries the built-in LED: a 1 k load to ground, added only while the pin is an output, so pinMode(13, INPUT_PULLUP) still behaves. The LED's cathode is on ground, so the pin sources to light it.
2. Memory map
| code flash | 256 KB at 0x0000_0000 |
| option-setting memory | 0x0000_0400, two words, stored and not decoded |
| SRAM | 32 KB at 0x2000_0000 |
| stack top | 0x2000_8000 |
| PORT and PFS | 0x4004_0000, section 3.1 and 3.2 |
| module stop | 0x4004_7000, section 3.7 |
| ADC14 unit 0 | 0x4005_C000, section 3.5 (believed) |
| SCI0..SCI9 | 0x4007_0000, 0x20 apart, section 3.4 |
| GPT0..GPT7 | 0x4007_8000, 0x100 apart, section 3.3 (believed) |
| USBFS | 0x4009_0000, section 3.6 (believed) |
The code flash really is at zero. There is no alias and no boot pin to choose one, so the vector table is at address 0 and VTOR's reset value is already right. A flash address that looks like a null pointer is the vector table, not a bug.
Every PT_LOAD segment must land inside the flash or the SRAM; anything else is refused with a reason, and the chip is left with no program. Data flash (8 KB at 0x4010_0000) and its programming interface are not modeled.
The option-setting memory at 0x0000_0400 is where a real RA4M1 reads OFS0 out of reset to decide whether the watchdogs start on their own. firmware/unor4/crt0.S puts a word there and link.ld asserts that it lands at 0x400; this model has no watchdog and decodes neither word. An image without it boots here and resets itself on a desk, which is why it is not optional.
The core is a Cortex-M4 with no FPU here. The RA4M1 has a single-precision FPU; cortexm-core implements ARMv7E-M's integer half and no VFP at all, CPACR is stored and grants nothing, and every VFP encoding raises UNDEFINSTR. Compile firmware -mfloat-abi=soft -mfpu=none. Floating-point arithmetic in a sketch works and is done in integer instructions; a hard-float binary built elsewhere faults on its first VFP instruction rather than returning a wrong number. Four priority bits, as on the part.
3. Peripheral registers
Only the subset below is implemented. Anything else inside a mapped block reads 0 and counts as a stray access; anything outside every block is an access fault. A module whose stop bit is set (section 3.7) reads 0 and counts as a stray access too, which is what "the clock is off" looks like from the bus.
3.1 PORT0..PORT5 (0x4004_0000, 0x20 apart)
| offset | register | halves |
|---|---|---|
0x00 |
PCNTR1 |
PDR low 16, PODR high 16 |
0x04 |
PCNTR2 |
PIDR low 16, EIDR high 16 (read only) |
0x08 |
PCNTR3 |
POSR low 16 sets, PORR high 16 clears (write only) |
0x0C |
PCNTR4 |
EOSR/EORR, stored |
PCNTR3 is this part's BSRR, with the halves the other way around from an STM32's: the low half sets. A bit set in both halves of one write ends up clear. digitalWrite is one store to it and cannot race an interrupt handler touching another bit.
PIDR reads the pin, not the latch: a push-pull output reads back what it is driving, an input or an open-drain output reads what the board last sampled off the net.
Ports 0 to 5 are modeled, which covers every pin the Minima brings out and every analog input the 64-pin package has. Pads are numbered port * 16 + pin.
3.2 PmnPFS (0x4004_0800, 0x40 per port, 4 bytes per pin) and PWPR (0x4004_0D03)
One 32-bit word per pin at 0x4004_0800 + 0x40*m + 4*n. The byte and halfword aliases the manual gives (PmnPFS_BY, PmnPFS_HA) are a union with the 32-bit register, so on this little-endian part they are its low byte and low halfword, which is why pinMode can be a single byte store.
| bit | name | meaning |
|---|---|---|
| 0 | PODR |
the output latch |
| 1 | PIDR |
the level on the pin, read only |
| 2 | PDR |
1 = output, 0 = input |
| 4 | PCR |
the internal pull-up |
| 6 | NCODR |
N-channel open drain |
| 10..11 | DSCR |
drive strength, stored |
| 12..13 | EOFR |
event on edge, stored |
| 14 | ISEL |
IRQ input enable, stored (section 3.8) |
| 15 | ASEL |
analog input enable |
| 16 | PMR |
1 = a peripheral owns the pin |
| 24..28 | PSEL |
which peripheral |
A pin with ASEL set is electrically high-Z whatever else the word says, and is the only kind the converter may sample. A pin with PMR set follows whichever modeled peripheral its PSEL names and ignores PODR; a PSEL this model does not implement leaves the pad alone rather than inventing a level.
PSEL values this model acts on: 0b00011 GPT and 0b00100 SCI. Both are believed, not verified (section 7).
PWPR is one byte at 0x4004_0D03. B0WI (bit 7) resets set and makes PFSWE (bit 6) unwritable; writing a zero clears it, and then writing PFSWE allows PFS writes. A write with B0WI set leaves PFSWE alone. A PmnPFS write while PFSWE is clear does not land, and the model counts it (protected_writes), because that is the silent failure this part is famous for.
3.3 GPT0..GPT7 (0x4007_8000, 0x100 apart)
GPT0 and GPT1 count 32 bits; GPT2 to GPT7 count 16.
| offset | register |
|---|---|
0x00 |
GTWP |
0x04 |
GTSTR |
0x08 |
GTSTP |
0x0C |
GTCLR |
0x2C |
GTCR |
0x30 |
GTUDDTYC |
0x34 |
GTIOR |
0x38 |
GTINTAD |
0x3C |
GTST |
0x40 |
GTBER |
0x48 |
GTCNT |
0x4C |
GTCCRA |
0x50 |
GTCCRB |
0x54 |
GTCCRC |
0x58 |
GTCCRE |
0x5C |
GTCCRD |
0x60 |
GTCCRF |
0x64 |
GTPR |
0x68 |
GTPBR |
GTCR.CST (bit 0) is the run bit. GTCR.TPCS (bits 24..26) is the prescaler, PCLKD / 4^TPCS, so 1, 4, 16, 64, 256 and 1024; a reserved value is treated as 1024. GTCR.MD (bits 16..18) is stored; only saw-wave up-counting is modeled. GTSTR, GTSTP and GTCLR take a bitmask of channels and start, stop or zero them. GTPR and GTPBR are written together, because the buffer transfer this model would do at a cycle end would carry the same value.
The counter is never stored as a number that ticks: it is computed from the CPU cycle as (cycle - started) / divider mod (GTPR + 1), so it cannot drift from the circuit and a GTCNT read halfway through a slice gives the count at that instruction.
The output is this model's own rule, and a simplification. GTIOR.OAE (bit 8) and GTIOR.OBE (bit 24) decide whether GTIOCnA and GTIOCnB are driven; the level is high while the count is below the channel's compare register and low otherwise. A compare of zero is permanently low and a compare above GTPR permanently high, which is what analogWrite(pin, 0) and analogWrite(pin, 255) need. The five-bit GTIOA and GTIOB level-select fields in GTIOR, which on silicon can produce an inverted output or a toggle, are stored and read back and not decoded. firmware/unor4/src/pwm.c writes the setting a real GPT would need anyway, so a build taken to a desk is configured and not merely enabled.
Which GPT output each PWM pin is:
| pin | pad | output |
|---|---|---|
3 |
P105 | GTIOC1B |
5 |
P107 | GTIOC2B |
6 |
P111 | GTIOC3A |
9 |
P304 | GTIOC5B |
10 |
P103 | GTIOC4B |
11 |
P411 | GTIOC6A |
That table is unverified (section 7). The six pins are the Minima's documented PWM pins; which channel and which output each one is, is this model's belief. The model and the runtime agree, so firmware built here works here.
GPT0 is deliberately unused by the runtime.
3.4 SCI0..SCI9 (0x4007_0000, 0x20 apart)
Byte registers, one after another: adjacent addresses are different registers, so a wider access reaches only the byte at the address given.
| offset | register |
|---|---|
0x00 |
SMR |
0x01 |
BRR |
0x02 |
SCR |
0x03 |
TDR |
0x04 |
SSR |
0x05 |
RDR |
0x06 |
SCMR |
0x07 |
SEMR |
0x08 |
SNFR |
0x09..0x0B |
SIMR1..SIMR3 |
0x0C |
SISR |
0x0D |
SPMR |
SCR: TE (5) and RE (4) are the two switches (there is no master enable), plus TIE (7), RIE (6), TEIE (2). SSR: TDRE (7), RDRF (6), ORER (5), FER (4), PER (3), TEND (2). The error flags and RDRF are cleared by writing a zero to them and are otherwise read only, and RDRF cannot stay clear while bytes are queued.
One bit is 32 * 4^CKS * (BRR + 1) PCLKA cycles, from the manual's N = PCLKA / (64 * 2^(2n-1) * B) - 1. SEMR.ABCS (bit 5) halves the divisor and SEMR.BGDM (bit 4) halves it again; both are applied. Everything else in SEMR, and SCMR, SNFR, SIMR*, SISR and SPMR, is stored and read back and changes nothing. Frame length follows SMR.CHR, SMR.PE and SMR.STOP.
Bytes leave at the bit rate, not instantly: TDR plus the shift register, so TDRE comes back as soon as a byte has started going out and TEND when the last one has finished. A Serial1.println costs simulated time (86.8 us a byte at 115200), exactly as it does on the desk.
SCI2 is the only channel on a pin here: TXD2 on D1 and RXD2 on D0. The other nine exist so that the channel number is the index; their bytes are counted and go nowhere.
A pad with PMR set and PSEL = SCI that is SCI2's transmitter idles high while SCR.TE is set, which is what a real TX line does between frames. The bytes themselves go to the host channel, not onto the wire as a waveform.
3.5 ADC14 unit 0 (0x4005_C000)
The base address and every offset in this section are unverified (section 7).
| offset | register |
|---|---|
0x00 |
ADCSR (16-bit) |
0x04, 0x06 |
ADANSA0, ADANSA1 |
0x08, 0x0A |
ADADS0, ADADS1 (stored) |
0x0C |
ADADC (stored) |
0x0E |
ADCER |
0x10 |
ADSTRGR (stored) |
0x12 |
ADEXICR (stored) |
0x20 + 2n |
ADDRn, one result per channel |
0xE0 + n |
ADSSTRn, sample time in ADC states, resets to 0x0B |
ADCSR.ADST (bit 15) starts a scan and stays set while it runs; firmware polls it, and clearing it abandons the scan. ADCSR.ADCS (bits 13..14): 0 single, 2 continuous; a continuous scan re-arms itself. ADCER.ADRFMT (bit 15) moves the result to the top of the sixteen bits; right-aligned by default.
A scan covers the channels selected in ADANSA0/ADANSA1 and takes each one's sample time plus twelve states of successive approximation. PCLKC is ICLK / 2, so one ADC state is two CPU cycles and a default one-channel conversion is 23 states, just under a microsecond, which firmware really does have to wait for.
ADDRn holds all fourteen bits. Nothing in the chip shifts them down to ten; analogRead's default resolution is the runtime's doing (section 6). Full scale is the 5 V rail.
Group scans, the temperature sensor, the internal reference, data averaging, self-diagnosis, double-trigger mode and every trigger but the software one are not modeled.
3.6 USBFS (0x4009_0000): a byte pipe, and nothing else
The base address and every offset in this section are unverified (section 7), and so, more importantly, is the idea that this is USB at all.
| offset | register |
|---|---|
0x00 |
SYSCFG |
0x04 |
SYSSTS0 (read only) |
0x08 |
DVSTCTR0 (stored) |
0x14 |
CFIFO |
0x20 |
CFIFOSEL |
0x22 |
CFIFOCTR |
0x30 |
INTENB0 (stored) |
0x40 |
INTSTS0 (stored) |
SYSCFG.USBE (bit 0) switches the controller on, SYSCFG.DPRPU (bit 4) attaches the D+ pull-up (which is what "plugging in" means), and SYSCFG.SCKE (bit 10) is the clock. Until the module stop bit is clear and both USBE and DPRPU are set, the pipe carries nothing.
CFIFOSEL.CURPIPE (bits 0..3) picks a pipe and CFIFOSEL.ISEL (bit 5) the direction: set to write, clear to read. CFIFO moves bytes. CFIFOCTR.DTLN (bits 0..8) reads how many are there, BVAL (bit 15) hands a write buffer over and BCLR (bit 14) throws it away. A buffer that reaches 64 bytes goes out on its own, because there is no host to wait for.
Nothing else about USB is here. No host, no bus, no reset, no SETUP packet, no descriptor, no enumeration, no addressing, no frame counter, no SOF, no double buffering, no NAK, no STALL, no pipe configuration and no interrupt. A sketch that drives this the way a CDC driver drives silicon will work; a sketch that waits for enumeration to complete, or inspects a descriptor request, will wait forever. That is why if (Serial) is true here as soon as begin() has run and false for a moment on a desk.
This is the place the model is deliberately not the chip, and pretending otherwise would be the one lie that matters.
3.7 Module stop (0x4004_7000)
| address | register | what this model decodes |
|---|---|---|
0x4004_7000 |
MSTPCRB |
SCIn at bit 31 - n, USBFS at bit 11 |
0x4004_7004 |
MSTPCRC |
stored |
0x4004_7008 |
MSTPCRD |
GPTn at bit 12 - n, ADC14 unit 0 at bit 16 |
A set bit stops the module, and every one of them resets set. The numbering counts down, which is the thing that surprises people. A stopped module's registers read 0 and the access is counted as stray; the port block and these registers themselves are always reachable, because something has to be.
3.8 SysTick, the NVIC, and the ICU that is not here
SysTick is the core's, with SYST_CALIB = 480,000: the reference clock is ICLK, so a 10 ms tick is 480,000 counts. Four priority bits. The vector table is sixteen system entries then thirty-two ICU slots.
On an RA those thirty-two have no fixed meaning: which peripheral event reaches IRQ n is programmed in the ICU's IELSRn register. The ICU's event links are not modeled, so nothing in this model raises a peripheral interrupt, IELSRn is not implemented, and PmnPFS.ISEL is stored and does nothing. SysTick, a core exception that needs no link, is the only interrupt that fires. That is why there is no attachInterrupt in the runtime (section 6), and it is said plainly rather than approximated: an ICU with invented event numbers would be worse than none.
4. Host channel
host_write puts bytes in both the USB pipe's receive buffer and SCI2's receive queue; host_read takes the bytes that have left either of them. A board has one host channel, and a sketch may be reading Serial, Serial1 or both.
That is Serial and Serial1 in a sketch and the serial monitor in the UI. Bytes are UTF-8 as far as the UI is concerned and opaque to the model.
The two ports are not the same in one visible way: Serial1's bytes leave at the bit rate and Serial's leave at the end of the slice they were handed over in, so a USB line really can land inside a UART one in the monitor. That is the board, not a bug.
5. Time model and the part
Picoseconds in a u64, like the kernel. The CPU runs at 48 MHz, so a cycle is 20833.33 ps, not a whole number, which is why time is never accumulated: it is recomputed from a cycle count as cycles * 1_000_000 / 48. A 10 us slice is exactly 480 cycles and exactly 10,000,000 ps, so slice boundaries never drift.
The cycle counter is anchored to kernel time at the start of every slice, so a timer cannot drift away from the circuit however the slices fall, and a parked core catches up on the cycles it slept through (SysTick included) without executing them.
A slice runs in two gears. Coarse is Cpu::run in chunks bounded by the next peripheral deadline; fine is one instruction at a time with the bus told the cycle each one starts at, which is what lets a pin change carry the cycle that caused it. A store to a port, GPT, SCI or USB register drops the slice into fine for the next 4,800 cycles.
probe is a bitmask: 1 running, 2 sleeping in WFI, 4 the built-in LED on pin 13 lit, 8 serial transmit in the last 20 ms, 16 serial receive. 0 with no program, held in reset, or crashed.
poke: 1 holds RESET, 0 releases it.
A crash (a BKPT, or a fault the core cannot return from) stops the board and puts one line on the host channel naming the PC, CFSR and HFSR:
firmware crashed at pc=0x00001000, BKPT #0 (CFSR 0x00000000, HFSR 0x00000000)
crt0.S points every vector it does not need at a handler that executes BKPT, so a fault says where it was rather than spinning silently.
6. Firmware runtime (firmware/unor4/)
An Arduino-shaped runtime written from scratch: setup() and loop(), pinMode, digitalWrite, digitalRead, shiftOut, analogRead, analogReadResolution, analogWrite, millis, micros, delay, delayMicroseconds, map, random, Serial and Serial1. No Arduino core, no ArduinoCore-renesas, no FSP, no CMSIS, no libc, nothing GPL.
Built with clang --target=thumbv7em-none-eabi -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -mfpu=none -Os and ld.lld against firmware/unor4/link.ld, with --nmagic so a two-kilobyte program is not padded to a 64 KB page. BOARD=unor4 is the one board this script builds.
- Pins. Every
pinModeunlocksPWPR, writes onePmnPFSword and locks it again.digitalWriteis one store toPCNTR3.INPUT_PULLDOWNis accepted and gives a plain input, because the part has no pull-down. - Time. SysTick at 1 kHz: reload 47,999, a whole number of cycles at 48 MHz, so
millisdoes not drift.microsis that counter plus what is left in SysTick's own down-counter, so one timer gives microsecond resolution over a full 32-bit range and every GPT channel is free foranalogWrite.delayexecutesWFIand parks; a second of simulated time costs about a thousand instructions instead of forty-eight million. analogReadreturns ten bits, 0..1023, from a fourteen-bit converter, because that is what an Arduino sketch expects.analogReadResolution(1..14)changes the shift, which lives insrc/analog.cand not in the chip.analogWriteis 0..255 at 490.0 Hz (48 MHz / 16 / 6123) on D3, D5, D6, D9, D10 and D11. 0 and 255 drop the GPT output enable and drive the pin, soanalogWrite(pin, 0)really is off; a pin that is not one of the six is driven low or high at the halfway point, as the Arduino cores do.Serialis the USB pipe and reaches no header pin.Serial1is SCI2 on D0 and D1, 8N1,BRR = PCLKA / (32 * baud) - 1rounded. Receive onSerial1is polled, because there is no ICU to deliver an interrupt; the model's queue behindRDRis deep enough that typing while the sketch is busy does not lose characters.- There is no
attachInterrupt, for the reason section 3.8 gives. A sketch polls. - Floating point works and is soft float.
Serial.print(float)reads the IEEE-754 bit pattern and never computes with it. String, the heap andtone()are the shared core's (firmware/lib): the heap runs from_endto the stack, andtone()is GPT PWM at 50 percent on D3, D5, D6, D9, D10 and D11, with a blocking bit-banged fallback for a timed note on any other pin. No I2C, no SPI.
The catalog program string is elf32 arm ra4m1.
Four examples, each budgeted at 16 KB: blink, button (a pushbutton on D2), serial (both ports, and an echo) and analog (a knob on A0 fading an LED on D9, printing ten bits and fourteen).
crates/unor4/tests/runtime.rs runs these ELFs against the model. Two of its cases exist to hold this document's numbers rather than restate them: the clock really is 48 MHz across two simulated seconds, and millis lands within 20 ms of the truth three seconds in.
7. What this model is sure of, and what it is not
Three groups. This section exists because a board model that quietly guesses an address is worse than one that says it did not know.
Taken from the RA4M1 group user's manual and the Minima's own documentation. The core: a Cortex-M4 at 48 MHz with four priority bits. 256 KB of code flash at zero, 32 KB of SRAM at 0x2000_0000, 8 KB of data flash at 0x4010_0000. The option-setting memory at 0x0000_0400. PORT_BASE = 0x4004_0000 with a 0x20 stride, and PCNTR1..PCNTR4 at 0x00, 0x04, 0x08, 0x0C with the half-word meanings section 3.1 gives. PFS_BASE = 0x4004_0800 with a 0x40 stride and four bytes a pin, and the PmnPFS bit positions in section 3.2. PWPR at 0x4004_0D03 with B0WI at bit 7 and PFSWE at bit 6. MSTP_BASE = 0x4004_7000, that a set bit stops the module, and that the numbering counts down. SCI_BASE = 0x4007_0000 with a 0x20 stride, the byte-register layout in section 3.4, and the SCR/SSR/SMR bit positions and the bit-rate formula. That SCI2 is the Minima's Serial1 on D0 and D1, and that Serial is the on-die USB. The Uno R3 header and the RA4M1 pad behind each hole in section 1, less the two noted below. That A0 is AN009 and A1..A3 are AN000..AN002. That D3, D5, D6, D9, D10 and D11 are the PWM pins. That the board is 68.6 x 53.3 mm.
Believed, not verified. Named here so an image being taken to real silicon has a short list to check, all of it in one header, firmware/unor4/include/ra4m1.h:
GPT_BASE=0x4007_8000with a 0x100 stride, and every register offset inside a GPT channel (section 3.3).- Which GPT output each PWM pin is: the six-row table in section 3.3. This is the weakest claim in the document: the pins are right and the channels are a belief.
ADC_BASE=0x4005_C000and every offset inside ADC14 (section 3.5).A4andA5onAN021andAN022. The other four analog channels are not in this group.USB_BASE=0x4009_0000and every offset inside USBFS (section 3.6).- The
PSELencodings0b00011for GPT and0b00100for SCI (section 3.2). - The exact
MSTPCRB/MSTPCRDbit positions for USBFS (11) and ADC14 (16). The SCI and GPT bits follow the counting-down rule, which is not in this group.
Where the model and this document disagree with silicon, firmware built here still agrees with the model: it runs in the simulator and its register writes are in one header to correct.
Modeled, but not held to the manual's numbers. Behaviors rather than addresses, in the sorting docs/esp32c6.md section 7 set and every board contract here now follows:
- The clock is 48 MHz and the clock tree is not there. The module stop bits are gates; HOCO, MOCO, the PLL and
SCKDIVCRare not modeled, so whatever a sketch programs, the core runs at 48 MHz.crates/unor4/tests/runtime.rsholds that to the shipped firmware rather than to this sentence. - The GPT output is high below its compare register and low above it (section 3.3).
GTIOR's five-bit level-select fields are stored and not decoded, so an inverted or toggling output is not reproduced;analogWrite's duty is. - The slice has two gears, and the first store after a quiet spell is early, up to 10.7 us. Everything inside a burst is exact. The reasoning is
docs/stm32f411.mdsection 7's. - ADC14 has no error in it. A conversion is the straight line against a 5 V reference, sampled at the instant it started, with no sample-and-hold, no input impedance, no nonlinearity, no noise and no offset.
ADCER's self-diagnosis andADADC's averaging are stored and do nothing. - The pads are three states and a threshold. Push-pull at 5 V, open drain, high-Z, or a 35 kΩ internal pull-up, read back against half the supply, with no hysteresis, no drive-strength setting, no rise time and no current limit.
DSCRis stored. Serialis a byte pipe and the pipe never fills. Bytes handed over leave at the end of the slice rather than at a USB frame boundary,availableForWriteis always 1, andif (Serial)is a decision this model makes rather than a handshake it runs (section 3.6).- The board is an ideal supply:
5V,IOREFand3V3at rail impedance for ever, so nothing browns out. Start-up is a microsecond, where a real R4 spends its first moments in the bootloader. - There is no user button, because the board has none; the one button holds
RESETlow and arrives throughpoke.
Deliberately absent. Each of these was left out rather than invented, because its layout or its behavior is not something this model can reproduce honestly:
- The ICU and its event links. Section 3.8. With it go every peripheral interrupt,
attachInterrupt, and the IRQ pins. - The clock generation circuit: HOCO, MOCO, the PLL,
SCKDIVCR. The part is modeled as already running at 48 MHz, and a program that configures the clock tree writes into an unmapped block. - The AGT. The RA4M1's low-power timer, and the one the Arduino core uses for
millis. SysTick is enough here and is exact. - The watchdogs (IWDT and WDT), which is why the option-setting memory is stored and not decoded.
- I2C (IIC), SPI, CAN, the DTC, the CTSU touch unit, the RTC, the DAC, the comparators, the OPAMPs, the CRC and CAC units, and the data flash's programming interface.
- USB as a protocol. Section 3.6 is the whole of it.
- Flash programming and the boot ROM.
That is why a vendor FSP or Arduino core binary does not run here, and firmware built for this document does.