@typecad/mcu-atmega328p 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/mcu.ts ADDED
@@ -0,0 +1,164 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/mcu-atmega328p — MCU hardware definition
3
+ // ---------------------------------------------------------------------------
4
+
5
+ import type { MCUDefinition } from '@typecad/cuttlefish/api/schema';
6
+ import { MCU_PERIPHERALS } from './peripherals.js';
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // Pin capability shorthands
10
+ // ---------------------------------------------------------------------------
11
+
12
+ const NO = false as const;
13
+ const YES = true as const;
14
+
15
+ /** Shorthand: digital I/O only, with internal pull-up. */
16
+ const DIGITAL = {
17
+ digitalInput: YES, digitalOutput: YES,
18
+ analogInput: NO, analogOutput: NO,
19
+ pwm: NO, interrupt: NO,
20
+ pullUp: YES, pullDown: NO,
21
+ touch: NO, openDrain: NO,
22
+ } as const;
23
+
24
+ /** Shorthand: digital I/O + external-interrupt capable. */
25
+ const DIGITAL_INT = { ...DIGITAL, interrupt: YES } as const;
26
+
27
+ /** Shorthand: digital I/O + PWM. */
28
+ const DIGITAL_PWM = { ...DIGITAL, pwm: YES } as const;
29
+
30
+ /** Shorthand: digital I/O + PWM + interrupt. */
31
+ const DIGITAL_PWM_INT = { ...DIGITAL, pwm: YES, interrupt: YES } as const;
32
+
33
+ /** Shorthand: digital I/O + analog input. */
34
+ const ANALOG_IN = { ...DIGITAL, analogInput: YES } as const;
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // ATmega328P MCU Definition
38
+ // ---------------------------------------------------------------------------
39
+
40
+ export const ATmega328P: MCUDefinition = {
41
+ id: 'atmega328p',
42
+ name: 'ATmega328P',
43
+ architecture: 'avr',
44
+
45
+ // ----- Memory ------------------------------------------------------------
46
+ memory: {
47
+ flash: 32_768, // 32 KB
48
+ sram: 2_048, // 2 KB
49
+ eeprom: 1_024, // 1 KB
50
+ },
51
+
52
+ // ----- Pins --------------------------------------------------------------
53
+ pins: {
54
+ all: [
55
+ // Port D pins (PD0–PD7)
56
+ { number: 0, gpio: 0, name: 'PD0', aliases: ['RX'], capabilities: DIGITAL_INT,
57
+ functions: [{ type: 'uart', instance: 0, role: 'rx' }],
58
+ alternateFunctions: ['UART0 RX'],
59
+ warnings: ['Using PD0 as GPIO will interfere with UART0 receive'],
60
+ unsafe: true, notes: 'UART RX pin' },
61
+ { number: 1, gpio: 1, name: 'PD1', aliases: ['TX'], capabilities: DIGITAL_INT,
62
+ functions: [{ type: 'uart', instance: 0, role: 'tx' }],
63
+ alternateFunctions: ['UART0 TX'],
64
+ warnings: ['Using PD1 as GPIO will interfere with UART0 transmit'],
65
+ unsafe: true, notes: 'UART TX pin' },
66
+ { number: 2, gpio: 2, name: 'PD2', capabilities: DIGITAL_INT },
67
+ { number: 3, gpio: 3, name: 'PD3', capabilities: DIGITAL_PWM_INT,
68
+ functions: [{ type: 'pwm', instance: 0, role: 'OC2B', timer: 'timer2' }] },
69
+ { number: 4, gpio: 4, name: 'PD4', capabilities: DIGITAL },
70
+ { number: 5, gpio: 5, name: 'PD5', capabilities: DIGITAL_PWM,
71
+ functions: [{ type: 'pwm', instance: 0, role: 'OC0B', timer: 'timer0' }] },
72
+ { number: 6, gpio: 6, name: 'PD6', capabilities: DIGITAL_PWM,
73
+ functions: [{ type: 'pwm', instance: 0, role: 'OC0A', timer: 'timer0' }] },
74
+ { number: 7, gpio: 7, name: 'PD7', capabilities: DIGITAL },
75
+
76
+ // Port B pins (PB0–PB5)
77
+ { number: 8, gpio: 8, name: 'PB0', capabilities: DIGITAL },
78
+ { number: 9, gpio: 9, name: 'PB1', capabilities: DIGITAL_PWM,
79
+ functions: [{ type: 'pwm', instance: 0, role: 'OC1A', timer: 'timer1' }] },
80
+ { number: 10, gpio: 10, name: 'PB2', aliases: ['SS'], capabilities: DIGITAL_PWM,
81
+ functions: [
82
+ { type: 'pwm', instance: 0, role: 'OC1B', timer: 'timer1' },
83
+ { type: 'spi', instance: 0, role: 'cs' },
84
+ ],
85
+ alternateFunctions: ['SPI0 CS'] },
86
+ { number: 11, gpio: 11, name: 'PB3', aliases: ['MOSI'], capabilities: DIGITAL_PWM,
87
+ functions: [
88
+ { type: 'pwm', instance: 0, role: 'OC2A', timer: 'timer2' },
89
+ { type: 'spi', instance: 0, role: 'mosi' },
90
+ ],
91
+ alternateFunctions: ['SPI0 MOSI'],
92
+ warnings: ['Using PB3 as GPIO will interfere with SPI0 MOSI'] },
93
+ { number: 12, gpio: 12, name: 'PB4', aliases: ['MISO'], capabilities: DIGITAL,
94
+ functions: [{ type: 'spi', instance: 0, role: 'miso' }],
95
+ alternateFunctions: ['SPI0 MISO'],
96
+ warnings: ['Using PB4 as GPIO will interfere with SPI0 MISO'] },
97
+ { number: 13, gpio: 13, name: 'PB5', aliases: ['SCK'], capabilities: DIGITAL,
98
+ functions: [{ type: 'spi', instance: 0, role: 'sck' }],
99
+ alternateFunctions: ['SPI0 SCK'],
100
+ warnings: ['PB5 is SPI0 SCK'] },
101
+
102
+ // Port C pins (PC0–PC5)
103
+ { number: 14, gpio: 14, name: 'PC0', capabilities: ANALOG_IN,
104
+ functions: [{ type: 'adc', instance: 0, role: 'ch0' }] },
105
+ { number: 15, gpio: 15, name: 'PC1', capabilities: ANALOG_IN,
106
+ functions: [{ type: 'adc', instance: 0, role: 'ch1' }] },
107
+ { number: 16, gpio: 16, name: 'PC2', capabilities: ANALOG_IN,
108
+ functions: [{ type: 'adc', instance: 0, role: 'ch2' }] },
109
+ { number: 17, gpio: 17, name: 'PC3', capabilities: ANALOG_IN,
110
+ functions: [{ type: 'adc', instance: 0, role: 'ch3' }] },
111
+ { number: 18, gpio: 18, name: 'PC4', aliases: ['SDA'], capabilities: ANALOG_IN,
112
+ functions: [
113
+ { type: 'adc', instance: 0, role: 'ch4' },
114
+ { type: 'i2c', instance: 0, role: 'sda' },
115
+ ],
116
+ alternateFunctions: ['I2C0 SDA', 'ADC ch4'],
117
+ warnings: ['Using PC4 as GPIO will interfere with I2C0 SDA'] },
118
+ { number: 19, gpio: 19, name: 'PC5', aliases: ['SCL'], capabilities: ANALOG_IN,
119
+ functions: [
120
+ { type: 'adc', instance: 0, role: 'ch5' },
121
+ { type: 'i2c', instance: 0, role: 'scl' },
122
+ ],
123
+ alternateFunctions: ['I2C0 SCL', 'ADC ch5'],
124
+ warnings: ['Using PC5 as GPIO will interfere with I2C0 SCL'] },
125
+ ],
126
+
127
+ digital: [
128
+ 'PD0', 'PD1', 'PD2', 'PD3', 'PD4', 'PD5', 'PD6', 'PD7',
129
+ 'PB0', 'PB1', 'PB2', 'PB3', 'PB4', 'PB5',
130
+ 'PC0', 'PC1', 'PC2', 'PC3', 'PC4', 'PC5',
131
+ ],
132
+ analog: ['PC0', 'PC1', 'PC2', 'PC3', 'PC4', 'PC5'],
133
+ pwm: ['PD3', 'PD5', 'PD6', 'PB1', 'PB2', 'PB3'],
134
+ unsafe: ['PD0', 'PD1'],
135
+
136
+ i2c: { 0: { sda: 'PC4', scl: 'PC5' } },
137
+ spi: { 0: { mosi: 'PB3', miso: 'PB4', sck: 'PB5', cs: 'PB2' } },
138
+ uart: {
139
+ 0: { tx: 'PD1', rx: 'PD0' },
140
+ 1: { tx: 'PD2', rx: 'PD3' },
141
+ },
142
+ },
143
+
144
+ // ----- Peripherals -------------------------------------------------------
145
+ peripherals: MCU_PERIPHERALS,
146
+
147
+ // ----- Features ----------------------------------------------------------
148
+ features: {
149
+ multicore: false,
150
+ coreCount: 1,
151
+ deepSleep: false,
152
+ watchdog: true,
153
+ externalInterrupts: true,
154
+ hardwareRng: false,
155
+ fpu: false,
156
+ },
157
+
158
+ // ----- Build config ------------------------------------------------------
159
+ build: {
160
+ extraFlags: ['-mmcu=atmega328p'],
161
+ },
162
+ };
163
+
164
+ export default ATmega328P;
@@ -0,0 +1,216 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/mcu-atmega328p — Hardware peripheral descriptions
3
+ //
4
+ // Describes the peripherals built into the ATmega328P silicon.
5
+ // These are properties of the chip, not the board — every ATmega328P has
6
+ // exactly the same peripheral count regardless of what board it's on.
7
+ //
8
+ // Source: ATmega328P datasheet, Section 2 — Block Diagram / Peripheral Summary
9
+ // ---------------------------------------------------------------------------
10
+
11
+ import type {
12
+ PeripheralInstance,
13
+ ADCDefinition,
14
+ PWMDefinition,
15
+ TimerDefinition,
16
+ } from '@typecad/cuttlefish/api/schema';
17
+ import {
18
+ I2CBus,
19
+ SPIBus,
20
+ SerialPort,
21
+ i2cName,
22
+ spiName,
23
+ serialName,
24
+ createHALInstances,
25
+ } from '@typecad/hal';
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // UART — 1 USART peripheral
29
+ // ---------------------------------------------------------------------------
30
+
31
+ /**
32
+ * USART peripherals on the ATmega328P.
33
+ * The ATmega328P has a single USART with full-duplex TX/RX.
34
+ */
35
+ export const UART_INSTANCES: readonly PeripheralInstance[] = [
36
+ { instance: 0, defaultPins: { tx: 'PD1', rx: 'PD0' } },
37
+ ] as const;
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // I2C (TWI) — 1 Two-Wire Interface
41
+ // ---------------------------------------------------------------------------
42
+
43
+ /**
44
+ * I2C/TWI peripherals on the ATmega328P.
45
+ * Single TWI peripheral with SDA/SCL on Port C.
46
+ */
47
+ export const I2C_INSTANCES: readonly PeripheralInstance[] = [
48
+ { instance: 0, defaultPins: { sda: 'PC4', scl: 'PC5' } },
49
+ ] as const;
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // SPI — 1 SPI peripheral
53
+ // ---------------------------------------------------------------------------
54
+
55
+ /**
56
+ * SPI peripherals on the ATmega328P.
57
+ * Single SPI peripheral in Master/Slave mode.
58
+ */
59
+ export const SPI_INSTANCES: readonly PeripheralInstance[] = [
60
+ { instance: 0, defaultPins: { mosi: 'PB3', miso: 'PB4', sck: 'PB5', cs: 'PB2' } },
61
+ ] as const;
62
+
63
+ // ---------------------------------------------------------------------------
64
+ // ADC — 1 ADC with 6 (single-ended) channels on Port C
65
+ // ---------------------------------------------------------------------------
66
+
67
+ /**
68
+ * ADC peripheral on the ATmega328P.
69
+ * 10-bit successive approximation ADC with 6 single-ended channels on PC0–PC5,
70
+ * plus internal channels for temperature sensor and bandgap reference.
71
+ *
72
+ * Note: referenceVoltage and referenceVoltages are board-dependent (determined
73
+ * by the board's power supply voltage). They are provided as chip-typical
74
+ * defaults (5V) and should be overridden by the board package if the board
75
+ * runs at a different voltage (e.g. 3.3V Pro Mini).
76
+ */
77
+ export const ADC_INSTANCES: readonly ADCDefinition[] = [
78
+ {
79
+ instance: 0,
80
+ channels: 6,
81
+ resolution: 10,
82
+ maxValue: 1023, // (1 << 10) - 1
83
+ referenceVoltage: 5.0, // chip-typical default; board may override
84
+ referenceVoltages: {
85
+ DEFAULT: 5.0, // VCC — board-dependent
86
+ INTERNAL: 1.1, // internal 1.1V bandgap reference
87
+ },
88
+ },
89
+ ] as const;
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // PWM — 6 channels from 3 timers
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /**
96
+ * PWM capabilities on the ATmega328P.
97
+ * 6 PWM channels derived from Timer0 (2 ch), Timer1 (2 ch), Timer2 (2 ch).
98
+ * 8-bit resolution on Timer0/Timer2, up to 16-bit on Timer1 (but framework
99
+ * defaults often use 8-bit for all).
100
+ */
101
+ export const PWM_CAPABILITIES: PWMDefinition = {
102
+ channels: 6,
103
+ resolution: 8,
104
+ maxFrequency: 62_500, // at 16 MHz with default prescaler
105
+ } as const;
106
+
107
+ /**
108
+ * PWM output pin assignments.
109
+ * Maps each PWM output compare channel to its physical pin.
110
+ */
111
+ export const PWM_PIN_MAP = {
112
+ /** Timer0 Channel A — PD6 */
113
+ OC0A: 'PD6',
114
+ /** Timer0 Channel B — PD5 */
115
+ OC0B: 'PD5',
116
+ /** Timer1 Channel A — PB1 */
117
+ OC1A: 'PB1',
118
+ /** Timer1 Channel B — PB2 */
119
+ OC1B: 'PB2',
120
+ /** Timer2 Channel A — PB3 */
121
+ OC2A: 'PB3',
122
+ /** Timer2 Channel B — PD3 */
123
+ OC2B: 'PD3',
124
+ } as const;
125
+
126
+ // ---------------------------------------------------------------------------
127
+ // Timers — 3 hardware timers
128
+ // ---------------------------------------------------------------------------
129
+
130
+ /**
131
+ * Hardware timers on the ATmega328P.
132
+ * Timer0 is typically reserved for system timing functions (millis/delay)
133
+ * (type: 'sys'). Timer1 and Timer2 are available for general application use.
134
+ */
135
+ export const TIMER_INSTANCES: readonly TimerDefinition[] = [
136
+ {
137
+ instance: 0,
138
+ type: 'sys',
139
+ bits: 8,
140
+ frequency: 16_000_000,
141
+ features: ['pwm', 'interrupt'],
142
+ },
143
+ {
144
+ instance: 1,
145
+ type: 'general',
146
+ bits: 16,
147
+ frequency: 16_000_000,
148
+ features: ['pwm', 'interrupt', 'capture', 'compare'],
149
+ },
150
+ {
151
+ instance: 2,
152
+ type: 'general',
153
+ bits: 8,
154
+ frequency: 16_000_000,
155
+ features: ['pwm', 'interrupt'],
156
+ },
157
+ ] as const;
158
+
159
+ // ---------------------------------------------------------------------------
160
+ // External interrupts
161
+ // ---------------------------------------------------------------------------
162
+
163
+ /**
164
+ * External interrupt pins on the ATmega328P.
165
+ * Only PD2 (INT0) and PD3 (INT1) support hardware external interrupts.
166
+ * Pin-change interrupts are available on all pins but are handled separately.
167
+ */
168
+ export const EXTERNAL_INTERRUPTS = [
169
+ { instance: 0, pin: 'PD2' }, // INT0
170
+ { instance: 1, pin: 'PD3' }, // INT1
171
+ ] as const;
172
+
173
+ // ---------------------------------------------------------------------------
174
+ // Aggregate MCU peripheral description
175
+ // ---------------------------------------------------------------------------
176
+
177
+ /**
178
+ * Complete hardware peripheral description for the ATmega328P.
179
+ * Board packages can import this and spread it into their BoardDefinition,
180
+ * overriding board-specific fields (aliases, reference voltages, etc.).
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * // In a board package:
185
+ * import { MCU_PERIPHERALS } from '@typecad/mcu-atmega328p';
186
+ *
187
+ * export const MyBoard: BoardDefinition = {
188
+ * // ...
189
+ * peripherals: {
190
+ * ...MCU_PERIPHERALS,
191
+ * aliases: { UART0: 'Serial', I2C0: 'Wire', SPI0: 'SPI' },
192
+ * },
193
+ * };
194
+ * ```
195
+ */
196
+ export const MCU_PERIPHERALS = {
197
+ i2c: [...I2C_INSTANCES],
198
+ spi: [...SPI_INSTANCES],
199
+ uart: [...UART_INSTANCES],
200
+ adc: [...ADC_INSTANCES],
201
+ pwm: PWM_CAPABILITIES,
202
+ timers: [...TIMER_INSTANCES],
203
+ } as const;
204
+
205
+ // ---------------------------------------------------------------------------
206
+ // HAL object instances — auto-generated from peripheral definitions
207
+ // ---------------------------------------------------------------------------
208
+
209
+ /** I2C bus instances */
210
+ export const [I2C0] = createHALInstances(I2C_INSTANCES, i => new I2CBus(i2cName(i)));
211
+
212
+ /** SPI bus instances */
213
+ export const [SPI0] = createHALInstances(SPI_INSTANCES, i => new SPIBus(spiName(i)));
214
+
215
+ /** UART/Serial instances */
216
+ export const [UART0] = createHALInstances(UART_INSTANCES, i => new SerialPort(serialName(i)));
package/src/pins.ts ADDED
@@ -0,0 +1,74 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/mcu-atmega328p — Datasheet pin definitions
3
+ //
4
+ // Each pin is a Pin instance created via Pin.fromPort() using the MCU port
5
+ // name from the ATmega328P datasheet. The port name is the canonical identity;
6
+ // framework-specific pin numbers are resolved at
7
+ // transpile time via the arduino-map.
8
+ // ---------------------------------------------------------------------------
9
+
10
+ import { Pin } from '@typecad/hal';
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // Port D (PD0–PD7) — 8-bit bidirectional I/O port
14
+ // DIP-28 pins 2–6, 9–11
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export const PD0 = Pin.fromPort('PD0');
18
+ export const PD1 = Pin.fromPort('PD1');
19
+ export const PD2 = Pin.fromPort('PD2');
20
+ export const PD3 = Pin.fromPort('PD3');
21
+ export const PD4 = Pin.fromPort('PD4');
22
+ export const PD5 = Pin.fromPort('PD5');
23
+ export const PD6 = Pin.fromPort('PD6');
24
+ export const PD7 = Pin.fromPort('PD7');
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Port B (PB0–PB7) — 8-bit bidirectional I/O port
28
+ // DIP-28 pins 12–19 (PB6/PB7 are crystal oscillator, not GPIO)
29
+ // ---------------------------------------------------------------------------
30
+
31
+ export const PB0 = Pin.fromPort('PB0');
32
+ export const PB1 = Pin.fromPort('PB1');
33
+ export const PB2 = Pin.fromPort('PB2');
34
+ export const PB3 = Pin.fromPort('PB3');
35
+ export const PB4 = Pin.fromPort('PB4');
36
+ export const PB5 = Pin.fromPort('PB5');
37
+ export const PB6 = Pin.fromPort('PB6');
38
+ export const PB7 = Pin.fromPort('PB7');
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Port C (PC0–PC6) — 7-bit bidirectional I/O port (PC6 is RESET on DIP-28)
42
+ // DIP-28 pins 23–28
43
+ // ---------------------------------------------------------------------------
44
+
45
+ export const PC0 = Pin.fromPort('PC0');
46
+ export const PC1 = Pin.fromPort('PC1');
47
+ export const PC2 = Pin.fromPort('PC2');
48
+ export const PC3 = Pin.fromPort('PC3');
49
+ export const PC4 = Pin.fromPort('PC4');
50
+ export const PC5 = Pin.fromPort('PC5');
51
+ export const PC6 = Pin.fromPort('PC6');
52
+
53
+ // ---------------------------------------------------------------------------
54
+ // Convenience aliases (Silicon-level defaults)
55
+ // ---------------------------------------------------------------------------
56
+
57
+ /** I2C data line (PC4). */
58
+ export const SDA = PC4;
59
+ /** I2C clock line (PC5). */
60
+ export const SCL = PC5;
61
+
62
+ /** SPI master-out / slave-in (PB3). */
63
+ export const MOSI = PB3;
64
+ /** SPI master-in / slave-out (PB4). */
65
+ export const MISO = PB4;
66
+ /** SPI clock (PB5). */
67
+ export const SCK = PB5;
68
+ /** SPI slave select (PB2). */
69
+ export const SS = PB2;
70
+
71
+ /** UART transmit (PD1). */
72
+ export const TX = PD1;
73
+ /** UART receive (PD0). */
74
+ export const RX = PD0;