@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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 typecad0
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,461 @@
1
+ # @typecad/mcu-atmega328p
2
+
3
+ MCU definition package for the **ATmega328P** microcontroller. Provides datasheet-level pin definitions, hardware peripheral descriptions, and framework pin mappings used by the TypeCAD transpiler and board packages.
4
+
5
+ ---
6
+
7
+ ## Purpose
8
+
9
+ MCU packages (`@typecad/mcu-*`) are the **hardware abstraction layer between the chip and the framework**. They answer three fundamental questions:
10
+
11
+ 1. **What pins exist on this chip?** — Exports typed `Pin` objects using canonical port names from the MCU datasheet (e.g. `PD0`, `PB5`, `PC0`).
12
+ 2. **What peripherals are built into the silicon?** — Describes the hardware peripherals the MCU provides: how many I2C/SPI/UART controllers, ADC channels, timers, PWM capabilities, etc.
13
+ 3. **How do port names map to framework pin numbers?** — Provides lookup tables so the transpiler can resolve `Pin.fromPort('PB5')` → Arduino pin `13`.
14
+
15
+ MCU packages are **framework-agnostic**. They don't know about Arduino, PlatformIO, or any specific board — they only know the chip itself. Board packages (e.g. `@typecad/board-arduino-uno`) import from MCU packages and add board-specific aliases, wiring, and metadata.
16
+
17
+ ### Package Layering
18
+
19
+ ```
20
+ ┌─────────────────────────────────────────────────┐
21
+ │ User sketch │
22
+ │ import { D13, LED, UART0 } from '@typecad/...' │
23
+ └──────────────────────┬──────────────────────────┘
24
+ │ imports from
25
+ ┌──────────────────────▼──────────────────────────┐
26
+ │ Board package (board-arduino-uno) │
27
+ │ • Arduino pin aliases (D0–D13, A0–A5) │
28
+ │ • Convenience aliases (LED, SDA, SCL, TX, RX) │
29
+ │ • Peripheral instances (I2C0, SPI0, UART0) │
30
+ │ • BoardDefinition (board-level metadata) │
31
+ │ • Timing, interrupt, and utility functions │
32
+ └──────────────────────┬──────────────────────────┘
33
+ │ imports pins + peripherals from
34
+ ┌──────────────────────▼──────────────────────────┐
35
+ │ MCU package (mcu-atmega328p) ◄── THIS PACKAGE│
36
+ │ • Datasheet pin definitions (PD0–PD7, etc.) │
37
+ │ • Hardware peripheral descriptions (I2C, SPI, │
38
+ │ UART, ADC, timers, PWM) │
39
+ │ • Framework pin mappings (ARDUINO_PIN_MAP) │
40
+ └──────────────────────┬──────────────────────────┘
41
+ │ depends on
42
+ ┌──────────────────────▼──────────────────────────┐
43
+ │ Core / HAL / Schema │
44
+ │ Pin, Pin.fromPort(), type definitions │
45
+ └─────────────────────────────────────────────────┘
46
+ ```
47
+
48
+ ---
49
+
50
+ ## What's Inside
51
+
52
+ ### `src/pins.ts` — Datasheet Pin Definitions
53
+
54
+ Exports one `Pin` constant per GPIO port on the ATmega328P, using [`Pin.fromPort()`](../hal/src/gpio.ts:201) with the canonical port name from the datasheet:
55
+
56
+ ```typescript
57
+ import { Pin } from '@typecad/hal';
58
+
59
+ export const PD0 = Pin.fromPort('PD0'); // Port D, bit 0
60
+ export const PD1 = Pin.fromPort('PD1'); // Port D, bit 1
61
+ // ...
62
+ export const PB5 = Pin.fromPort('PB5'); // Port B, bit 5
63
+ export const PC0 = Pin.fromPort('PC0'); // Port C, bit 0
64
+ // ...
65
+ ```
66
+
67
+ **Why `Pin.fromPort()` instead of `new Pin(number)`?**
68
+
69
+ - `Pin.fromPort('PB5')` stores the port name as the canonical identity. The transpiler resolves it to the correct framework pin number at compile time using the pin mapping.
70
+ - `new Pin(13)` hardcodes a framework-specific pin number, which breaks if the same chip is used with a different framework or board variant.
71
+ - Port names are universal — `PB5` means the same physical pin on every ATmega328P board, whether it's an Arduino Uno, a Pro Mini, or a bare DIP-28 on a breadboard.
72
+
73
+ ### `src/arduino-map.ts` — Arduino Pin Mapping
74
+
75
+ Maps MCU port names to Arduino framework pin numbers:
76
+
77
+ ```typescript
78
+ export const ARDUINO_PIN_MAP: Readonly<Record<string, number>> = {
79
+ PD0: 0, PD1: 1, PD2: 2, PD3: 3,
80
+ PD4: 4, PD5: 5, PD6: 6, PD7: 7,
81
+ PB0: 8, PB1: 9, PB2: 10, PB3: 11,
82
+ PB4: 12, PB5: 13,
83
+ PC0: 14, PC1: 15, PC2: 16, PC3: 17,
84
+ PC4: 18, PC5: 19,
85
+ };
86
+
87
+ export const ARDUINO_ANALOG_OFFSET = 14;
88
+
89
+ export const ARDUINO_PIN_REVERSE: Readonly<Record<number, string>> = { ... };
90
+ ```
91
+
92
+ This mapping is **per-chip**, not per-board. An ATtiny85 has `A2 = PB4` while the ATmega328P has `A2 = PC2`. That's why it lives in the MCU package, not in the framework or board package.
93
+
94
+ ### `src/index.ts` — Barrel Export
95
+
96
+ Re-exports everything from `pins.ts` and `arduino-map.ts`.
97
+
98
+ ---
99
+
100
+ ## Hardware Peripherals
101
+
102
+ The ATmega328P has a fixed set of hardware peripherals baked into the silicon. These are properties of the **chip**, not the board — every ATmega328P has exactly the same peripheral count regardless of what board it's soldered to.
103
+
104
+ ### ATmega328P Peripheral Summary
105
+
106
+ | Peripheral | Count | Details |
107
+ |---|---|---|
108
+ | **UART** | 1 | USART0 — full-duplex serial, TX/RX on PD1/PD0 |
109
+ | **I2C** (TWI) | 1 | Two-Wire Interface — SDA on PC4, SCL on PC5 |
110
+ | **SPI** | 1 | MOSI on PB3, MISO on PB4, SCK on PB5, SS on PB2 |
111
+ | **ADC** | 1 | 10-bit, 6 channels on PC0–PC5 (plus temperature + VBG) |
112
+ | **Timers** | 3 | Timer0 (8-bit, system), Timer1 (16-bit), Timer2 (8-bit) |
113
+ | **PWM** | 6 channels | From Timer0 (OC0A/OC0B), Timer1 (OC1A/OC1B), Timer2 (OC2A/OC2B) |
114
+ | **External Interrupts** | 2 | INT0 on PD2, INT1 on PD3 |
115
+ | **Watchdog** | 1 | Independent watchdog timer |
116
+
117
+ ### Peripheral-to-Pin Mapping
118
+
119
+ The MCU datasheet defines which pins are hardwired to each peripheral. This mapping is fixed by the silicon:
120
+
121
+ ```
122
+ UART0: TX = PD1, RX = PD0
123
+ I2C0: SDA = PC4, SCL = PC5
124
+ SPI0: MOSI = PB3, MISO = PB4, SCK = PB5, SS = PB2
125
+ ADC0: CH0 = PC0, CH1 = PC1, CH2 = PC2, CH3 = PC3, CH4 = PC4, CH5 = PC5
126
+ PWM: OC0A = PD6, OC0B = PD5 (Timer0)
127
+ OC1A = PB1, OC1B = PB2 (Timer1)
128
+ OC2A = PB3, OC2B = PD3 (Timer2)
129
+ EXTI: INT0 = PD2, INT1 = PD3
130
+ ```
131
+
132
+ Board packages consume this information when building their [`BoardDefinition`](../board-arduino-uno/src/index.ts:46) manifest. The board definition adds board-level concerns (which peripheral aliases to use, which pins are exposed as headers, memory specs, build flags) on top of the MCU's hardware facts.
133
+
134
+ ### Why Peripherals Belong in MCU Packages
135
+
136
+ The number of I2C controllers, UART ports, and ADC channels is determined by the silicon die:
137
+
138
+ - **Same chip, different boards** — An ATmega328P on an Arduino Uno, Pro Mini, or bare breadboard all have exactly 1 UART, 1 I2C, 1 SPI, and 3 timers. Duplicating this in every board package is redundant and error-prone.
139
+ - **Transpiler validation** — The transpiler uses peripheral counts to detect bus conflicts (e.g., two I2C devices on the same bus) and pin-capability mismatches (e.g., calling `pwm()` on a non-PWM pin). These checks are chip-level, not board-level.
140
+ - **Peripheral instances** — When user code creates `new I2CBus(i2cName(0))`, the instance number `0` refers to the MCU's I2C0 peripheral. The MCU package defines how many instances exist.
141
+
142
+ Currently, the peripheral definitions are strictly separated from board-level concerns. The MCU package exports a structured peripheral description that board packages import and extend.
143
+
144
+ ```typescript
145
+ // src/peripherals.ts in an MCU package
146
+ export const UART_INSTANCES: readonly PeripheralInstance[] = [
147
+ { instance: 0, defaultPins: { tx: 'PD1', rx: 'PD0' } },
148
+ ];
149
+ // ... (I2C, SPI, ADC, etc.)
150
+
151
+ export const MCU_PERIPHERALS = {
152
+ uart: [...UART_INSTANCES],
153
+ i2c: [...I2C_INSTANCES],
154
+ spi: [...SPI_INSTANCES],
155
+ // ...
156
+ } as const;
157
+ ```
158
+
159
+ Board packages then reference the MCU's peripheral data rather than duplicating it:
160
+
161
+ ```typescript
162
+ // In a board package
163
+ import { MCU_PERIPHERALS } from '@typecad/mcu-atmega328p';
164
+
165
+ export const ArduinoUno: BoardDefinition = {
166
+ // ...
167
+ peripherals: {
168
+ ...MCU_PERIPHERALS,
169
+ aliases: { UART0: 'Serial', I2C0: 'Wire', SPI0: 'SPI' }, // board-specific
170
+ // board-specific overrides (e.g., reference voltages) go here
171
+ },
172
+ };
173
+ ```
174
+
175
+ ### Auto-Generated HAL Instances
176
+
177
+ MCU packages also export the concrete HAL instances (`UART0`, `I2C0`, etc.) corresponding to their physical peripherals. To minimize boilerplate and prevent mismatches, these are auto-generated from the peripheral definition arrays using `createHALInstances` from `@typecad/hal`:
178
+
179
+ ```typescript
180
+ import { createHALInstances, SerialPort, serialName } from '@typecad/hal';
181
+
182
+ /** UART/Serial instances */
183
+ export const [UART0] = createHALInstances(UART_INSTANCES, i => new SerialPort(serialName(i)));
184
+ ```
185
+
186
+ Because `createHALInstances` returns a mapped array, you simply destructure exactly the instances you've defined in the array. This single line dynamically creates the correct HAL objects and ensures `UART0` is strongly typed and statically exported.
187
+
188
+
189
+ ---
190
+
191
+ ## How Board Packages Use This
192
+
193
+ The [`@typecad/board-arduino-uno`](../board-arduino-uno/src/pins.ts) package demonstrates the pattern:
194
+
195
+ ```typescript
196
+ // Re-export datasheet pins from the MCU package
197
+ export {
198
+ PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7,
199
+ PB0, PB1, PB2, PB3, PB4, PB5,
200
+ PC0, PC1, PC2, PC3, PC4, PC5,
201
+ } from '@typecad/mcu-atmega328p';
202
+
203
+ // Import for local aliasing
204
+ import { PD0, PB5, PC4, PC5, /* ... */ } from '@typecad/mcu-atmega328p';
205
+
206
+ // Board-specific aliases
207
+ export const D13 = PB5; // Arduino digital pin 13
208
+ export const A0 = PC0; // Arduino analog pin A0
209
+ export const LED = PB5; // On-board LED
210
+ export const SDA = PC4; // I2C data
211
+ export const SCL = PC5; // I2C clock
212
+ ```
213
+
214
+ The board package also provides the [`BoardDefinition`](../board-arduino-uno/src/index.ts:46) manifest with pin capabilities, peripheral assignments, memory specs, and build configuration.
215
+
216
+ ---
217
+
218
+ ## Creating a New `mcu-*` Package
219
+
220
+ Follow these steps to create an MCU package for a new microcontroller.
221
+
222
+ ### 1. Scaffold the Package
223
+
224
+ ```
225
+ packages/mcu-<chip>/
226
+ ├── package.json
227
+ ├── tsconfig.json
228
+ └── src/
229
+ ├── index.ts
230
+ ├── pins.ts
231
+ ├── peripherals.ts ← hardware peripheral descriptions
232
+ └── arduino-map.ts (or other framework mappings)
233
+ ```
234
+
235
+ ### 2. `package.json`
236
+
237
+ ```json
238
+ {
239
+ "name": "@typecad/mcu-<chip>",
240
+ "version": "0.1.0",
241
+ "description": "TypeCAD MCU definition for <ChipName>",
242
+ "type": "commonjs",
243
+ "main": "./dist/index.js",
244
+ "types": "./dist/index.d.ts",
245
+ "exports": {
246
+ ".": {
247
+ "types": "./dist/index.d.ts",
248
+ "default": "./dist/index.js"
249
+ }
250
+ },
251
+ "files": ["dist"],
252
+ "scripts": {
253
+ "build": "tsc"
254
+ },
255
+ "dependencies": {
256
+ "@typecad/cuttlefish": "*",
257
+ "@typecad/hal": "*"
258
+ },
259
+ "license": "MIT"
260
+ }
261
+ ```
262
+
263
+ ### 3. `tsconfig.json`
264
+
265
+ ```json
266
+ {
267
+ "compilerOptions": {
268
+ "composite": true,
269
+ "target": "ES2021",
270
+ "module": "Node16",
271
+ "moduleResolution": "Node16",
272
+ "strict": true,
273
+ "declaration": true,
274
+ "declarationMap": true,
275
+ "sourceMap": true,
276
+ "rootDir": "src",
277
+ "outDir": "dist"
278
+ },
279
+ "include": ["src/**/*.ts"],
280
+ "references": [
281
+ { "path": "../cuttlefish" },
282
+ { "path": "../hal" }
283
+ ]
284
+ }
285
+ ```
286
+
287
+ ### 4. `src/pins.ts` — Define Pins from the Datasheet
288
+
289
+ Open the MCU datasheet and find the GPIO port table. Create one `Pin.fromPort()` export per GPIO pin:
290
+
291
+ ```typescript
292
+ import { Pin } from '@typecad/hal';
293
+
294
+ // Port A — 8-bit bidirectional I/O port
295
+ export const PA0 = Pin.fromPort('PA0');
296
+ export const PA1 = Pin.fromPort('PA1');
297
+ // ... up to PA7
298
+
299
+ // Port B — 8-bit bidirectional I/O port
300
+ export const PB0 = Pin.fromPort('PB0');
301
+ // ...
302
+
303
+ // Port C — etc.
304
+ ```
305
+
306
+ **Guidelines:**
307
+
308
+ - **Use datasheet port names** (`PD0`, `PB5`, `PC0`) — these are the canonical identifiers.
309
+ - **Include ALL GPIO pins** on the chip, even if some are shared with crystal oscillators or reset pins. Add a comment noting any restrictions (e.g. `// PB6/PB7 are crystal oscillator on Uno, not GPIO`).
310
+ - **Do NOT include power, ground, or purely analog-only pins** that have no GPIO capability.
311
+ - **Do NOT create board-specific aliases** (like `LED` or `D13`) — those belong in board packages.
312
+
313
+ ### 5. `src/peripherals.ts` — Describe Hardware Peripherals
314
+
315
+ Open the datasheet's peripheral overview chapter. Document every hardware peripheral built into the silicon using definition arrays, and auto-generate the concrete HAL instances:
316
+
317
+ ```typescript
318
+ import { PeripheralInstance } from '@typecad/cuttlefish/api/schema';
319
+ import { createHALInstances, SerialPort, serialName } from '@typecad/hal';
320
+
321
+ export const UART_INSTANCES: readonly PeripheralInstance[] = [
322
+ { instance: 0, pins: { tx: 'PA0', rx: 'PA1' } },
323
+ { instance: 1, pins: { tx: 'PA2', rx: 'PA3' } },
324
+ ] as const;
325
+
326
+ // ... define I2C, SPI, etc.
327
+
328
+ /**
329
+ * Hardware peripherals on the <ChipName>.
330
+ * Source: <ChipName> datasheet, Section X — Peripheral Description
331
+ */
332
+ export const MCU_PERIPHERALS = {
333
+ uart: [...UART_INSTANCES],
334
+ // ...
335
+ } as const;
336
+
337
+ // Auto-generate HAL objects
338
+ export const [UART0, UART1] = createHALInstances(UART_INSTANCES, i => new SerialPort(serialName(i)));
339
+ ```
340
+
341
+ **What to include:**
342
+
343
+ - **Instance count** — How many of each peripheral the silicon provides (e.g., ESP32 has 3 I2C, 4 SPI, 3 UART; ATmega328P has 1 of each). Update the destructuring arrays to match exactly the available instances.
344
+ - **Pin assignments** — Which MCU port pins are hardwired to each peripheral function. These are fixed by the silicon and cannot be changed.
345
+ - **Capabilities** — Resolution (ADC/DAC bits), timer widths, max frequencies, etc.
346
+ - **Alternate pin functions** — If the chip supports pin muxing (like ESP32's GPIO matrix), document the default and alternate pin assignments.
347
+
348
+
349
+ **What NOT to include:**
350
+
351
+ - **Board-specific aliases** — `UART0 → 'Serial'` is an Arduino convention, not a chip property.
352
+ - **Reference voltages** — These depend on the board's power supply (5V vs 3.3V), not the silicon.
353
+ - **Framework-specific names** — `Wire`, `SPI`, `Serial` are Arduino names; other frameworks use different names.
354
+
355
+ ### 6. `src/arduino-map.ts` — Add Framework Pin Mappings (if applicable)
356
+
357
+ If the chip is used with the Arduino framework, provide the port-name-to-Arduino-pin-number mapping:
358
+
359
+ ```typescript
360
+ /**
361
+ * Arduino pin number for each MCU port name.
362
+ * Source: Arduino <variant>/pins_arduino.h
363
+ */
364
+ export const ARDUINO_PIN_MAP: Readonly<Record<string, number>> = {
365
+ PA0: 0, PA1: 1, // ...
366
+ };
367
+
368
+ /** Offset where analog pin numbering starts. */
369
+ export const ARDUINO_ANALOG_OFFSET = 14;
370
+
371
+ /** Reverse map: Arduino pin number → MCU port name. */
372
+ export const ARDUINO_PIN_REVERSE: Readonly<Record<number, string>> = {};
373
+ for (const [port, num] of Object.entries(ARDUINO_PIN_MAP)) {
374
+ (ARDUINO_PIN_REVERSE as Record<number, string>)[num] = port;
375
+ }
376
+ ```
377
+
378
+ **Source this from the actual Arduino core variant header** (e.g. `variants/standard/pins_arduino.h` for ATmega328P). Do not guess — wrong mappings cause silent hardware bugs.
379
+
380
+ If the chip supports multiple Arduino board variants with different pin mappings, export the most common one as `ARDUINO_PIN_MAP` and add additional named maps as needed (e.g., `ARDUINO_PIN_MAP_PRO_MINI`).
381
+
382
+ ### 7. `src/index.ts` — Barrel Export
383
+
384
+ ```typescript
385
+ export * from './pins';
386
+ export * from './peripherals';
387
+ export * from './arduino-map';
388
+ ```
389
+
390
+ ### 8. Add to Workspace
391
+
392
+ In the monorepo root `pnpm-workspace.yaml`, the package is automatically included if it's under `packages/`. Make sure to:
393
+
394
+ 1. Run `pnpm install` from the workspace root to link the new package.
395
+ 2. Reference it from any board package that uses this MCU:
396
+ ```json
397
+ // packages/board-<board>/package.json
398
+ {
399
+ "dependencies": {
400
+ "@typecad/mcu-<chip>": "*"
401
+ }
402
+ }
403
+ ```
404
+
405
+ ---
406
+
407
+ ## When to Create an MCU Package vs. a Board Package
408
+
409
+ | Scenario | Create |
410
+ |---|---|
411
+ | New microcontroller chip (e.g. ATtiny85, STM32F103) | `mcu-*` package |
412
+ | New board using an existing chip (e.g. Arduino Nano with ATmega328P) | `board-*` package only — reuse the `mcu-atmega328p` package |
413
+ | New board with a new chip | Both — `mcu-*` for the chip, `board-*` for the board |
414
+ | Chip used with a non-Arduino framework | Add framework mapping to existing `mcu-*` package |
415
+
416
+ ### Key Principles
417
+
418
+ - **One MCU package per chip family.** The ATmega328P has one package shared by Arduino Uno, Pro Mini, Nano, and any custom board.
419
+ - **Pin names are datasheet port names.** `PD0` means the same thing on every ATmega328P board. Board-specific names like `RX` or `D0` go in the board package.
420
+ - **Peripheral counts are silicon facts.** The number of UART/I2C/SPI controllers is determined by the chip die, not the board. Document them once in the MCU package.
421
+ - **Framework mappings are per-chip, not per-board.** The Arduino pin mapping for ATmega328P is the same whether it's on an Uno or a Pro Mini. Only the board package changes (different aliases, different peripheral wiring).
422
+ - **MCU packages have no runtime code.** Everything is resolved at transpile time. The `Pin.fromPort()` calls exist only for the type system and transpiler — they produce no C++ output.
423
+
424
+ ---
425
+
426
+ ## ATmega328P Pin Reference
427
+
428
+ | Port | DIP-28 Pin | Arduino Pin | Peripheral Functions | Notes |
429
+ |------|-----------|-------------|---------------------|-------|
430
+ | PC6 | 1 | — | RESET | Reset pin (usually not GPIO) |
431
+ | PD0 | 2 | D0 / RX | UART0 RX | INT0 (external interrupt) |
432
+ | PD1 | 3 | D1 / TX | UART0 TX | INT1 (external interrupt) |
433
+ | PD2 | 4 | D2 | INT0 | External interrupt 0 |
434
+ | PD3 | 5 | D3~ | INT1, OC2B | PWM (Timer2) |
435
+ | PD4 | 6 | D4 | — | — |
436
+ | VCC | 7, 20 | — | — | Power |
437
+ | GND | 8, 22 | — | — | Ground |
438
+ | PB6 | 9 | — | TOSC1 | Crystal oscillator |
439
+ | PB7 | 10 | — | TOSC2 | Crystal oscillator |
440
+ | PD5 | 11 | D5~ | OC0B | PWM (Timer0) |
441
+ | PD6 | 12 | D6~ | OC0A | PWM (Timer0) |
442
+ | PD7 | 13 | D7 | — | — |
443
+ | PB0 | 14 | D8 | — | — |
444
+ | PB1 | 15 | D9~ | OC1A | PWM (Timer1) |
445
+ | PB2 | 16 | D10~ | OC1B, SPI SS | PWM (Timer1) |
446
+ | PB3 | 17 | D11~ | OC2A, SPI MOSI | PWM (Timer2) |
447
+ | PB4 | 18 | D12 | SPI MISO | — |
448
+ | PB5 | 19 | D13 | SPI SCK | On-board LED |
449
+ | AVCC | 21 | — | — | Analog power supply |
450
+ | PC0 | 23 | A0 / D14 | ADC ch0 | — |
451
+ | PC1 | 24 | A1 / D15 | ADC ch1 | — |
452
+ | PC2 | 25 | A2 / D16 | ADC ch2 | — |
453
+ | PC3 | 26 | A3 / D17 | ADC ch3 | — |
454
+ | PC4 | 27 | A4 / SDA | ADC ch4, I2C SDA | — |
455
+ | PC5 | 28 | A5 / SCL | ADC ch5, I2C SCL | — |
456
+
457
+ ---
458
+
459
+ ## License
460
+
461
+ MIT
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Arduino pin number for each MCU port name.
3
+ * Port name → Arduino digital/analog pin number.
4
+ */
5
+ export declare const ARDUINO_PIN_MAP: Readonly<Record<string, number>>;
6
+ /**
7
+ * The offset where analog pin numbering starts.
8
+ * Arduino analogRead(A0) maps to pin 14 on ATmega328P.
9
+ */
10
+ export declare const ARDUINO_ANALOG_OFFSET = 14;
11
+ /**
12
+ * Reverse map: Arduino pin number → MCU port name.
13
+ * Used by the transpiler to resolve bare names like D13 → PB5.
14
+ */
15
+ export declare const ARDUINO_PIN_REVERSE: Readonly<Record<number, string>>;
@@ -0,0 +1,37 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/mcu-atmega328p — Arduino core pin mapping
3
+ //
4
+ // Maps MCU port names to Arduino framework pin numbers.
5
+ // Source: Arduino AVR core, variants/standard/pins_arduino.h
6
+ //
7
+ // This mapping is per-chip — an ATtiny85 has A2=PB4 while ATmega328P has
8
+ // A2=PC2. It lives in the MCU package, NOT in the framework package.
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Arduino pin number for each MCU port name.
12
+ * Port name → Arduino digital/analog pin number.
13
+ */
14
+ export const ARDUINO_PIN_MAP = {
15
+ // Port D — Arduino digital pins 0–7
16
+ PD0: 0, PD1: 1, PD2: 2, PD3: 3,
17
+ PD4: 4, PD5: 5, PD6: 6, PD7: 7,
18
+ // Port B — Arduino digital pins 8–13
19
+ PB0: 8, PB1: 9, PB2: 10, PB3: 11,
20
+ PB4: 12, PB5: 13,
21
+ // Port C — Arduino analog pins A0–A5 (pin numbers 14–19)
22
+ PC0: 14, PC1: 15, PC2: 16, PC3: 17,
23
+ PC4: 18, PC5: 19,
24
+ };
25
+ /**
26
+ * The offset where analog pin numbering starts.
27
+ * Arduino analogRead(A0) maps to pin 14 on ATmega328P.
28
+ */
29
+ export const ARDUINO_ANALOG_OFFSET = 14;
30
+ /**
31
+ * Reverse map: Arduino pin number → MCU port name.
32
+ * Used by the transpiler to resolve bare names like D13 → PB5.
33
+ */
34
+ export const ARDUINO_PIN_REVERSE = {};
35
+ for (const [port, num] of Object.entries(ARDUINO_PIN_MAP)) {
36
+ ARDUINO_PIN_REVERSE[num] = port;
37
+ }
@@ -0,0 +1,15 @@
1
+ export * from './pins.js';
2
+ export * from './peripherals.js';
3
+ export * from './mcu.js';
4
+ export * from './arduino-map.js';
5
+ /**
6
+ * Structured manifest consumed by the TypeCAD CLI for contract-based
7
+ * board generation. Provides pin names and peripheral instance names
8
+ * without requiring the CLI to text-scrape compiled output.
9
+ */
10
+ export declare const TypeCADManifest: {
11
+ /** All MCU port-level pin names (e.g. 'PB5', 'PC4'). */
12
+ readonly pinNames: readonly ["PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6"];
13
+ /** All HAL peripheral instance names exported from this package. */
14
+ readonly peripheralNames: readonly ["I2C0", "SPI0", "UART0"];
15
+ };
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/mcu-atmega328p — MCU definition package
3
+ //
4
+ // Provides datasheet-level pin definitions, hardware peripheral descriptions,
5
+ // and framework pin mappings for the ATmega328P microcontroller.
6
+ // Board packages (e.g. board-arduino-uno) import from here and add
7
+ // board-specific aliases and wiring.
8
+ // ---------------------------------------------------------------------------
9
+ // Re-export all pin definitions
10
+ export * from './pins.js';
11
+ // Re-export hardware peripheral descriptions
12
+ export * from './peripherals.js';
13
+ // Re-export MCU definition
14
+ export * from './mcu.js';
15
+ // Re-export Arduino pin mapping (used by transpiler and framework strategy)
16
+ export * from './arduino-map.js';
17
+ /**
18
+ * Structured manifest consumed by the TypeCAD CLI for contract-based
19
+ * board generation. Provides pin names and peripheral instance names
20
+ * without requiring the CLI to text-scrape compiled output.
21
+ */
22
+ export const TypeCADManifest = {
23
+ /** All MCU port-level pin names (e.g. 'PB5', 'PC4'). */
24
+ pinNames: [
25
+ 'PD0', 'PD1', 'PD2', 'PD3', 'PD4', 'PD5', 'PD6', 'PD7',
26
+ 'PB0', 'PB1', 'PB2', 'PB3', 'PB4', 'PB5', 'PB6', 'PB7',
27
+ 'PC0', 'PC1', 'PC2', 'PC3', 'PC4', 'PC5', 'PC6'
28
+ ],
29
+ /** All HAL peripheral instance names exported from this package. */
30
+ peripheralNames: ['I2C0', 'SPI0', 'UART0'],
31
+ };
package/dist/mcu.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { MCUDefinition } from '@typecad/cuttlefish/api/schema';
2
+ export declare const ATmega328P: MCUDefinition;
3
+ export default ATmega328P;