alpaca2-stubs 1.0.2__tar.gz
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.
- alpaca2_stubs-1.0.2/PKG-INFO +140 -0
- alpaca2_stubs-1.0.2/README.md +132 -0
- alpaca2_stubs-1.0.2/alpaca2_stubs.egg-info/PKG-INFO +140 -0
- alpaca2_stubs-1.0.2/alpaca2_stubs.egg-info/SOURCES.txt +13 -0
- alpaca2_stubs-1.0.2/alpaca2_stubs.egg-info/dependency_links.txt +1 -0
- alpaca2_stubs-1.0.2/alpaca2_stubs.egg-info/top_level.txt +6 -0
- alpaca2_stubs-1.0.2/command/__init__.pyi +20 -0
- alpaca2_stubs-1.0.2/dac/__init__.pyi +82 -0
- alpaca2_stubs-1.0.2/dac/driver.pyi +36 -0
- alpaca2_stubs-1.0.2/helper/__init__.pyi +40 -0
- alpaca2_stubs-1.0.2/link/__init__.pyi +21 -0
- alpaca2_stubs-1.0.2/pyproject.toml +28 -0
- alpaca2_stubs-1.0.2/setup.cfg +4 -0
- alpaca2_stubs-1.0.2/utime/__init__.pyi +11 -0
- alpaca2_stubs-1.0.2/version/__init__.pyi +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpaca2-stubs
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Stub files for ALPACA 2.0 for NB2420 Electronic Instrumentation course of TU Delft
|
|
5
|
+
License-Expression: CC-BY-4.0
|
|
6
|
+
Requires-Python: >=3.14
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
Stubs for # ALPACA 2.0
|
|
10
|
+
|
|
11
|
+
> © Copyright Delft University of Technology, CC BY 4.0.
|
|
12
|
+
|
|
13
|
+
**ALPACA (Advanced Learning Platform for Analog Circuits and Automation)** is a device built on RP2 and MicroPython and equipped with several digital tools to be a guide in introduction to digital systems and electronics for NB2420 Electronic Instrumentation course of TU Delft.
|
|
14
|
+
|
|
15
|
+
ALPACA splits work across two Picos:
|
|
16
|
+
|
|
17
|
+
- **Student Pico**: the board a student writes code on via Belay. It exposes a tiny RPC
|
|
18
|
+
client so student programs can ask the Helper to do things. Student Pico is equiiped with
|
|
19
|
+
a double channel DAC.
|
|
20
|
+
|
|
21
|
+
- **Helper**: a self-contained instrument. It drives an LCD and runs
|
|
22
|
+
a set of measurement screens (voltmeter, component/resistance tester) that
|
|
23
|
+
the user can cycles through. It also answers commands sent by the Student
|
|
24
|
+
over a UART link.
|
|
25
|
+
|
|
26
|
+
A host-side CLI (`alpaca`) handles flashing your code onto the boards and
|
|
27
|
+
opening a serial REPL, so you never have to manage USB ports by hand.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
The Student and Helper talk over UART0 with a crossover wiring and a shared
|
|
31
|
+
ground:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Student GP00 (TX) ──► Helper GP13 (RX)
|
|
35
|
+
Student GP01 (RX) ◄── Helper GP12 (TX)
|
|
36
|
+
GND ◄──────────────► GND
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Repository layout
|
|
40
|
+
|
|
41
|
+
`📁 alpaca` folder contains the libraries for Picos.
|
|
42
|
+
`📁 src/alpaca` contains the desktop-side library and the ALPACA CLI for
|
|
43
|
+
managing the boards (`src/alpaca/cli`). It is published on PyPI as `alpaca2`,
|
|
44
|
+
but the import name and the command stay `alpaca`, so installed users write
|
|
45
|
+
`from alpaca import list_boards`.
|
|
46
|
+
|
|
47
|
+
`alpaca/common` is copied alongside `alpaca/student` or `alpaca/helper` onto
|
|
48
|
+
each board at sync time, which is why on-device imports are flat
|
|
49
|
+
(`from command import ...`, `from link import ...`).
|
|
50
|
+
|
|
51
|
+
Therefore if the folders are like this
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
📁 alpaca/
|
|
55
|
+
📁 common/
|
|
56
|
+
📄 A.py
|
|
57
|
+
📁 student/
|
|
58
|
+
📄 B.py
|
|
59
|
+
📁 helper/
|
|
60
|
+
📄 C.py
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
using `alpaca sync` will copy the files to the root as:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
🍓 HelperPico
|
|
67
|
+
📄 A.py
|
|
68
|
+
📄 C.py
|
|
69
|
+
|
|
70
|
+
🍓 StudentPico
|
|
71
|
+
📄 A.py
|
|
72
|
+
📄 B.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Setup
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv sync
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This installs the project and exposes the `alpaca` command. Outside a
|
|
82
|
+
checkout, install the published package instead:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install alpaca2 # or: uv tool install alpaca2
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
### Sync your code onto the boards
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run alpaca sync
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This discovers connected Picos, copies the `common` + `student`/`helper` code
|
|
97
|
+
onto each, and soft-resets them. To drop into a REPL on one board right after
|
|
98
|
+
syncing:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run alpaca sync --connect student
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Open a serial REPL
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv run alpaca connect student # or: helper
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Picking a board
|
|
111
|
+
|
|
112
|
+
The first time the CLI needs a board it lists the connected Picos in a terminal
|
|
113
|
+
menu. Hovering an entry lights that board's onboard LED so you can tell
|
|
114
|
+
which is which, and you can choose to remember the selection — it's cached per
|
|
115
|
+
role under `.alpaca/` so later runs skip the prompt.
|
|
116
|
+
|
|
117
|
+
## Building
|
|
118
|
+
|
|
119
|
+
The repository workflow should build and publish stubs, and assemble firmware images on creation of a version tag.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
git tag v1.0.0
|
|
123
|
+
git push origin v1.0.0
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The MicroPython version for firmware is set inside the `build-firmware.yml` (currently 1.28.0).
|
|
127
|
+
|
|
128
|
+
## MicroPython builtins
|
|
129
|
+
|
|
130
|
+
These stubs cover ALPACA itself. For `machine`, `rp2` and the rest of
|
|
131
|
+
the MicroPython standard library, install those stubs alongside:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
conda install pip
|
|
135
|
+
pip install micropython-rp2-stubs
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
They are not published on any conda channel, so they are not declared
|
|
139
|
+
as a dependency here. Without them only the MicroPython builtins stay
|
|
140
|
+
unresolved in your editor; the ALPACA stubs themselves work either way.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
Stubs for # ALPACA 2.0
|
|
2
|
+
|
|
3
|
+
> © Copyright Delft University of Technology, CC BY 4.0.
|
|
4
|
+
|
|
5
|
+
**ALPACA (Advanced Learning Platform for Analog Circuits and Automation)** is a device built on RP2 and MicroPython and equipped with several digital tools to be a guide in introduction to digital systems and electronics for NB2420 Electronic Instrumentation course of TU Delft.
|
|
6
|
+
|
|
7
|
+
ALPACA splits work across two Picos:
|
|
8
|
+
|
|
9
|
+
- **Student Pico**: the board a student writes code on via Belay. It exposes a tiny RPC
|
|
10
|
+
client so student programs can ask the Helper to do things. Student Pico is equiiped with
|
|
11
|
+
a double channel DAC.
|
|
12
|
+
|
|
13
|
+
- **Helper**: a self-contained instrument. It drives an LCD and runs
|
|
14
|
+
a set of measurement screens (voltmeter, component/resistance tester) that
|
|
15
|
+
the user can cycles through. It also answers commands sent by the Student
|
|
16
|
+
over a UART link.
|
|
17
|
+
|
|
18
|
+
A host-side CLI (`alpaca`) handles flashing your code onto the boards and
|
|
19
|
+
opening a serial REPL, so you never have to manage USB ports by hand.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
The Student and Helper talk over UART0 with a crossover wiring and a shared
|
|
23
|
+
ground:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Student GP00 (TX) ──► Helper GP13 (RX)
|
|
27
|
+
Student GP01 (RX) ◄── Helper GP12 (TX)
|
|
28
|
+
GND ◄──────────────► GND
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Repository layout
|
|
32
|
+
|
|
33
|
+
`📁 alpaca` folder contains the libraries for Picos.
|
|
34
|
+
`📁 src/alpaca` contains the desktop-side library and the ALPACA CLI for
|
|
35
|
+
managing the boards (`src/alpaca/cli`). It is published on PyPI as `alpaca2`,
|
|
36
|
+
but the import name and the command stay `alpaca`, so installed users write
|
|
37
|
+
`from alpaca import list_boards`.
|
|
38
|
+
|
|
39
|
+
`alpaca/common` is copied alongside `alpaca/student` or `alpaca/helper` onto
|
|
40
|
+
each board at sync time, which is why on-device imports are flat
|
|
41
|
+
(`from command import ...`, `from link import ...`).
|
|
42
|
+
|
|
43
|
+
Therefore if the folders are like this
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
📁 alpaca/
|
|
47
|
+
📁 common/
|
|
48
|
+
📄 A.py
|
|
49
|
+
📁 student/
|
|
50
|
+
📄 B.py
|
|
51
|
+
📁 helper/
|
|
52
|
+
📄 C.py
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
using `alpaca sync` will copy the files to the root as:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
🍓 HelperPico
|
|
59
|
+
📄 A.py
|
|
60
|
+
📄 C.py
|
|
61
|
+
|
|
62
|
+
🍓 StudentPico
|
|
63
|
+
📄 A.py
|
|
64
|
+
📄 B.py
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Setup
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv sync
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This installs the project and exposes the `alpaca` command. Outside a
|
|
74
|
+
checkout, install the published package instead:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install alpaca2 # or: uv tool install alpaca2
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
|
+
### Sync your code onto the boards
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv run alpaca sync
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This discovers connected Picos, copies the `common` + `student`/`helper` code
|
|
89
|
+
onto each, and soft-resets them. To drop into a REPL on one board right after
|
|
90
|
+
syncing:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run alpaca sync --connect student
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Open a serial REPL
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv run alpaca connect student # or: helper
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Picking a board
|
|
103
|
+
|
|
104
|
+
The first time the CLI needs a board it lists the connected Picos in a terminal
|
|
105
|
+
menu. Hovering an entry lights that board's onboard LED so you can tell
|
|
106
|
+
which is which, and you can choose to remember the selection — it's cached per
|
|
107
|
+
role under `.alpaca/` so later runs skip the prompt.
|
|
108
|
+
|
|
109
|
+
## Building
|
|
110
|
+
|
|
111
|
+
The repository workflow should build and publish stubs, and assemble firmware images on creation of a version tag.
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
git tag v1.0.0
|
|
115
|
+
git push origin v1.0.0
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The MicroPython version for firmware is set inside the `build-firmware.yml` (currently 1.28.0).
|
|
119
|
+
|
|
120
|
+
## MicroPython builtins
|
|
121
|
+
|
|
122
|
+
These stubs cover ALPACA itself. For `machine`, `rp2` and the rest of
|
|
123
|
+
the MicroPython standard library, install those stubs alongside:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
conda install pip
|
|
127
|
+
pip install micropython-rp2-stubs
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
They are not published on any conda channel, so they are not declared
|
|
131
|
+
as a dependency here. Without them only the MicroPython builtins stay
|
|
132
|
+
unresolved in your editor; the ALPACA stubs themselves work either way.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpaca2-stubs
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Stub files for ALPACA 2.0 for NB2420 Electronic Instrumentation course of TU Delft
|
|
5
|
+
License-Expression: CC-BY-4.0
|
|
6
|
+
Requires-Python: >=3.14
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
Stubs for # ALPACA 2.0
|
|
10
|
+
|
|
11
|
+
> © Copyright Delft University of Technology, CC BY 4.0.
|
|
12
|
+
|
|
13
|
+
**ALPACA (Advanced Learning Platform for Analog Circuits and Automation)** is a device built on RP2 and MicroPython and equipped with several digital tools to be a guide in introduction to digital systems and electronics for NB2420 Electronic Instrumentation course of TU Delft.
|
|
14
|
+
|
|
15
|
+
ALPACA splits work across two Picos:
|
|
16
|
+
|
|
17
|
+
- **Student Pico**: the board a student writes code on via Belay. It exposes a tiny RPC
|
|
18
|
+
client so student programs can ask the Helper to do things. Student Pico is equiiped with
|
|
19
|
+
a double channel DAC.
|
|
20
|
+
|
|
21
|
+
- **Helper**: a self-contained instrument. It drives an LCD and runs
|
|
22
|
+
a set of measurement screens (voltmeter, component/resistance tester) that
|
|
23
|
+
the user can cycles through. It also answers commands sent by the Student
|
|
24
|
+
over a UART link.
|
|
25
|
+
|
|
26
|
+
A host-side CLI (`alpaca`) handles flashing your code onto the boards and
|
|
27
|
+
opening a serial REPL, so you never have to manage USB ports by hand.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
The Student and Helper talk over UART0 with a crossover wiring and a shared
|
|
31
|
+
ground:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Student GP00 (TX) ──► Helper GP13 (RX)
|
|
35
|
+
Student GP01 (RX) ◄── Helper GP12 (TX)
|
|
36
|
+
GND ◄──────────────► GND
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Repository layout
|
|
40
|
+
|
|
41
|
+
`📁 alpaca` folder contains the libraries for Picos.
|
|
42
|
+
`📁 src/alpaca` contains the desktop-side library and the ALPACA CLI for
|
|
43
|
+
managing the boards (`src/alpaca/cli`). It is published on PyPI as `alpaca2`,
|
|
44
|
+
but the import name and the command stay `alpaca`, so installed users write
|
|
45
|
+
`from alpaca import list_boards`.
|
|
46
|
+
|
|
47
|
+
`alpaca/common` is copied alongside `alpaca/student` or `alpaca/helper` onto
|
|
48
|
+
each board at sync time, which is why on-device imports are flat
|
|
49
|
+
(`from command import ...`, `from link import ...`).
|
|
50
|
+
|
|
51
|
+
Therefore if the folders are like this
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
📁 alpaca/
|
|
55
|
+
📁 common/
|
|
56
|
+
📄 A.py
|
|
57
|
+
📁 student/
|
|
58
|
+
📄 B.py
|
|
59
|
+
📁 helper/
|
|
60
|
+
📄 C.py
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
using `alpaca sync` will copy the files to the root as:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
🍓 HelperPico
|
|
67
|
+
📄 A.py
|
|
68
|
+
📄 C.py
|
|
69
|
+
|
|
70
|
+
🍓 StudentPico
|
|
71
|
+
📄 A.py
|
|
72
|
+
📄 B.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Setup
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv sync
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This installs the project and exposes the `alpaca` command. Outside a
|
|
82
|
+
checkout, install the published package instead:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install alpaca2 # or: uv tool install alpaca2
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
### Sync your code onto the boards
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run alpaca sync
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This discovers connected Picos, copies the `common` + `student`/`helper` code
|
|
97
|
+
onto each, and soft-resets them. To drop into a REPL on one board right after
|
|
98
|
+
syncing:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run alpaca sync --connect student
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Open a serial REPL
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv run alpaca connect student # or: helper
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Picking a board
|
|
111
|
+
|
|
112
|
+
The first time the CLI needs a board it lists the connected Picos in a terminal
|
|
113
|
+
menu. Hovering an entry lights that board's onboard LED so you can tell
|
|
114
|
+
which is which, and you can choose to remember the selection — it's cached per
|
|
115
|
+
role under `.alpaca/` so later runs skip the prompt.
|
|
116
|
+
|
|
117
|
+
## Building
|
|
118
|
+
|
|
119
|
+
The repository workflow should build and publish stubs, and assemble firmware images on creation of a version tag.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
git tag v1.0.0
|
|
123
|
+
git push origin v1.0.0
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The MicroPython version for firmware is set inside the `build-firmware.yml` (currently 1.28.0).
|
|
127
|
+
|
|
128
|
+
## MicroPython builtins
|
|
129
|
+
|
|
130
|
+
These stubs cover ALPACA itself. For `machine`, `rp2` and the rest of
|
|
131
|
+
the MicroPython standard library, install those stubs alongside:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
conda install pip
|
|
135
|
+
pip install micropython-rp2-stubs
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
They are not published on any conda channel, so they are not declared
|
|
139
|
+
as a dependency here. Without them only the MicroPython builtins stay
|
|
140
|
+
unresolved in your editor; the ALPACA stubs themselves work either way.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
alpaca2_stubs.egg-info/PKG-INFO
|
|
4
|
+
alpaca2_stubs.egg-info/SOURCES.txt
|
|
5
|
+
alpaca2_stubs.egg-info/dependency_links.txt
|
|
6
|
+
alpaca2_stubs.egg-info/top_level.txt
|
|
7
|
+
command/__init__.pyi
|
|
8
|
+
dac/__init__.pyi
|
|
9
|
+
dac/driver.pyi
|
|
10
|
+
helper/__init__.pyi
|
|
11
|
+
link/__init__.pyi
|
|
12
|
+
utime/__init__.pyi
|
|
13
|
+
version/__init__.pyi
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
|
|
3
|
+
PING: Incomplete
|
|
4
|
+
LCD_PUTSTR: Incomplete
|
|
5
|
+
SET_PIN: Incomplete
|
|
6
|
+
AWG_R2R_LOAD: Incomplete
|
|
7
|
+
AWG_R2R_START: Incomplete
|
|
8
|
+
AWG_R2R_STOP: Incomplete
|
|
9
|
+
AWG_R2R_OFFSET: Incomplete
|
|
10
|
+
AWG_R2R_GEN: Incomplete
|
|
11
|
+
WAVE_SINE: Incomplete
|
|
12
|
+
WAVE_BLOCK: Incomplete
|
|
13
|
+
WAVE_TRIANGLE: Incomplete
|
|
14
|
+
WAVE_SAWTOOTH: Incomplete
|
|
15
|
+
COMMANDS: Incomplete
|
|
16
|
+
|
|
17
|
+
def pack_args(fmt, values):
|
|
18
|
+
"""Encode a tuple/list of values per a format string into bytes."""
|
|
19
|
+
def unpack_args(fmt, buf):
|
|
20
|
+
"""Decode bytes per a format string into a list of values."""
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import _thread
|
|
2
|
+
import micropython
|
|
3
|
+
import types
|
|
4
|
+
from _typeshed import Incomplete
|
|
5
|
+
from collections.abc import Callable as Callable
|
|
6
|
+
from dac.driver import MCP4922 as MCP4922
|
|
7
|
+
from machine import Pin as Pin, SPI as SPI
|
|
8
|
+
from typing import Literal
|
|
9
|
+
from utime import sleep_us as sleep_us, ticks_ms as ticks_ms
|
|
10
|
+
|
|
11
|
+
driver: Incomplete
|
|
12
|
+
|
|
13
|
+
class DAC:
|
|
14
|
+
channel: Literal[0, 1]
|
|
15
|
+
gain: Literal[1, 2]
|
|
16
|
+
v_ref: Incomplete
|
|
17
|
+
def __init__(self, channel: Literal['A', 'B'], v_ref: Literal[3000, 2048] = 3000, gain: Literal[1, 2] = 1) -> None: ...
|
|
18
|
+
def write(self, val: float): ...
|
|
19
|
+
def generate(self, generator: Callable[[float], float], frequency_hz: int, N: int = 100): ...
|
|
20
|
+
@staticmethod
|
|
21
|
+
def sync(worker_1: DACWorker, worker_2: DACWorker, resample: bool = True) -> SyncedDACWorker:
|
|
22
|
+
"""Drive two DAC channels simultaneously.
|
|
23
|
+
|
|
24
|
+
Takes two workers (as produced by ``DAC.generate``) that target
|
|
25
|
+
different channels and returns a single worker that interleaves both
|
|
26
|
+
signals over SPI, latching both outputs with one shared LDAC pulse so
|
|
27
|
+
the two channels update at exactly the same instant.
|
|
28
|
+
|
|
29
|
+
:param resample: when True (default), both AWG tables are regenerated
|
|
30
|
+
from their original functions at a shared sample count (the larger of
|
|
31
|
+
the two). When the two signals also share a sample period this lets the
|
|
32
|
+
worker drive both channels from a single index on one deadline, instead
|
|
33
|
+
of tracking each channel's deadline separately.
|
|
34
|
+
|
|
35
|
+
Usage::
|
|
36
|
+
|
|
37
|
+
worker_a = dac_a.generate(...)
|
|
38
|
+
worker_b = dac_b.generate(...)
|
|
39
|
+
with DAC.sync(worker_a, worker_b):
|
|
40
|
+
...
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
class DACWorker:
|
|
44
|
+
channel: Incomplete
|
|
45
|
+
dac: Incomplete
|
|
46
|
+
generator: Incomplete
|
|
47
|
+
frequency_hz: Incomplete
|
|
48
|
+
N: Incomplete
|
|
49
|
+
sample_period_us: Incomplete
|
|
50
|
+
awg_table: Incomplete
|
|
51
|
+
stop_flag_lock: Incomplete
|
|
52
|
+
def __init__(self, sample_period_us: int, awg_table: memoryview, channel: Literal[0, 1], dac: DAC, generator: Callable[[float], float], frequency_hz: int, N: int) -> None: ...
|
|
53
|
+
done: Incomplete
|
|
54
|
+
def __enter__(self): ...
|
|
55
|
+
def __exit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None) -> None: ...
|
|
56
|
+
@micropython.native
|
|
57
|
+
@staticmethod
|
|
58
|
+
def worker(sample_period_us: int, awg_table: memoryview, stop_flag_lock: _thread.LockType, done_lock: _thread.LockType, spi: SPI, cs: Pin, ldac: Pin): ...
|
|
59
|
+
|
|
60
|
+
class SyncedDACWorker:
|
|
61
|
+
"""Drives two channels from a single worker thread.
|
|
62
|
+
|
|
63
|
+
Both signals share one worker loop so their outputs are latched together
|
|
64
|
+
with one LDAC pulse. Each channel keeps its own sample period, so signals
|
|
65
|
+
of different frequencies stay phase-aligned while still updating in lockstep
|
|
66
|
+
whenever their deadlines coincide.
|
|
67
|
+
"""
|
|
68
|
+
sample_period_1: Incomplete
|
|
69
|
+
awg_table_1: Incomplete
|
|
70
|
+
sample_period_2: Incomplete
|
|
71
|
+
awg_table_2: Incomplete
|
|
72
|
+
stop_flag_lock: Incomplete
|
|
73
|
+
def __init__(self, worker_1: DACWorker, worker_2: DACWorker) -> None: ...
|
|
74
|
+
done: Incomplete
|
|
75
|
+
def __enter__(self): ...
|
|
76
|
+
def __exit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None) -> None: ...
|
|
77
|
+
@micropython.native
|
|
78
|
+
@staticmethod
|
|
79
|
+
def worker_locked(period: int, awg_table_1: memoryview, awg_table_2: memoryview, stop_flag_lock: _thread.LockType, done_lock: _thread.LockType, spi: SPI, cs: Pin, ldac: Pin): ...
|
|
80
|
+
@micropython.native
|
|
81
|
+
@staticmethod
|
|
82
|
+
def worker(period_1: int, awg_table_1: memoryview, period_2: int, awg_table_2: memoryview, stop_flag_lock: _thread.LockType, done_lock: _thread.LockType, spi: SPI, cs: Pin, ldac: Pin): ...
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import micropython
|
|
2
|
+
from _typeshed import Incomplete
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
DAC_12_BIT_LIMIT: Incomplete
|
|
6
|
+
|
|
7
|
+
class MCP4922:
|
|
8
|
+
"""
|
|
9
|
+
MCP4922 is a Digital to Analog Converter
|
|
10
|
+
|
|
11
|
+
It operates over SP and has two channels.
|
|
12
|
+
|
|
13
|
+
The 16-bit data is sent over TX (MOSI) Pin and 4-bit is reserved
|
|
14
|
+
for config (see MCP4922.write). The data for indiviual channels
|
|
15
|
+
is kept in the input register.
|
|
16
|
+
|
|
17
|
+
Setting LDAC to low moves inputs from input register to output
|
|
18
|
+
register, which allows both channels to be operated simeltanously.
|
|
19
|
+
"""
|
|
20
|
+
spi: Incomplete
|
|
21
|
+
cs: Incomplete
|
|
22
|
+
ldac: Incomplete
|
|
23
|
+
def __init__(self) -> None: ...
|
|
24
|
+
@micropython.native
|
|
25
|
+
def write(self, value: int, channel: Literal[0, 1] = 0, buffered: bool = False, gain: Literal[1, 2] = 1) -> bool:
|
|
26
|
+
"""Write a 12-bit value to DAC
|
|
27
|
+
:param channel: 0 for DAC A, 1 for DAC B.
|
|
28
|
+
:param value: Integer from 0 to 4095.
|
|
29
|
+
:param buffered: True to use VREF buffer, False for unbuffered.
|
|
30
|
+
:param gain: 1x or 2x output gain
|
|
31
|
+
|
|
32
|
+
:returns: whether the data was actually sent to DAC
|
|
33
|
+
"""
|
|
34
|
+
@micropython.native
|
|
35
|
+
def push(self) -> None:
|
|
36
|
+
"""Move input register to output"""
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import types
|
|
2
|
+
from _typeshed import Incomplete
|
|
3
|
+
|
|
4
|
+
link: Incomplete
|
|
5
|
+
|
|
6
|
+
def ping(): ...
|
|
7
|
+
def set_screen_text(text_up: str = '', text_down: str = ''): ...
|
|
8
|
+
def awg_r2r(samples, sample_rate_hz):
|
|
9
|
+
"""Play a waveform on the Helper's R-2R ladder DAC (GPIO0-9).
|
|
10
|
+
|
|
11
|
+
samples: iterable of 10-bit codes (0-1023, values are masked), looped
|
|
12
|
+
forever. sample_rate_hz: requested playback rate; returns the actual
|
|
13
|
+
rate achieved, which is lower if the requested rate is too fast.
|
|
14
|
+
"""
|
|
15
|
+
def awg_r2r_stop():
|
|
16
|
+
"""Stop the AWG and drive the ladder to 0."""
|
|
17
|
+
def awg_r2r_offset(magnitude, negative: bool = False):
|
|
18
|
+
"""Set the analog offset stage: magnitude 0.0-1.0 (PWM duty on
|
|
19
|
+
OFFSET_PWM), negative selects the sign via OFFSET_POL."""
|
|
20
|
+
|
|
21
|
+
class _Waveform:
|
|
22
|
+
"""A shortcut waveform the Helper synthesizes itself: playing it sends one
|
|
23
|
+
small payload instead of loading samples over the wire. Use it as a context
|
|
24
|
+
manager so the AWG stops on exit, or drive it with .start()/.stop()."""
|
|
25
|
+
frequency_hz: Incomplete
|
|
26
|
+
def __init__(self, waveform, frequency_hz, amplitude_vpp, duty_cycle) -> None: ...
|
|
27
|
+
def start(self): ...
|
|
28
|
+
def stop(self): ...
|
|
29
|
+
def __enter__(self): ...
|
|
30
|
+
def __exit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None): ...
|
|
31
|
+
|
|
32
|
+
class FunctionGenerator:
|
|
33
|
+
"""Shortcut waveforms on the Helper's R-2R ladder DAC (GPIO0-9). Amplitudes
|
|
34
|
+
are volts peak-to-peak around mid-rail, clipped to the ladder's 0-3.3V."""
|
|
35
|
+
def sine(self, frequency_hz, amplitude_vpp): ...
|
|
36
|
+
def block(self, frequency_hz, amplitude_vpp, duty_cycle: float = 0.5): ...
|
|
37
|
+
def triangle(self, frequency_hz, amplitude_vpp): ...
|
|
38
|
+
def sawtooth(self, frequency_hz, amplitude_vpp): ...
|
|
39
|
+
|
|
40
|
+
function_generator: Incomplete
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import micropython
|
|
2
|
+
from _typeshed import Incomplete
|
|
3
|
+
|
|
4
|
+
OK: Incomplete
|
|
5
|
+
ERR: Incomplete
|
|
6
|
+
|
|
7
|
+
class Link:
|
|
8
|
+
uart: Incomplete
|
|
9
|
+
timeout_ms: Incomplete
|
|
10
|
+
handlers: Incomplete
|
|
11
|
+
event_loop: Incomplete
|
|
12
|
+
event_times: Incomplete
|
|
13
|
+
def __init__(self, uart, timeout_ms: int = 1000) -> None: ...
|
|
14
|
+
@micropython.native
|
|
15
|
+
def call(self, opcode, *args):
|
|
16
|
+
"""Send a request and block for the reply. Returns the decoded
|
|
17
|
+
result or raises RuntimeError on an ERR reply."""
|
|
18
|
+
def register(self, opcode): ...
|
|
19
|
+
def event(self, func): ...
|
|
20
|
+
@micropython.native
|
|
21
|
+
def serve(self) -> None: ...
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "alpaca2-stubs"
|
|
3
|
+
version = "1.0.2"
|
|
4
|
+
description = "Stub files for ALPACA 2.0 for NB2420 Electronic Instrumentation course of TU Delft"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
license = "CC-BY-4.0"
|
|
8
|
+
|
|
9
|
+
[build-system]
|
|
10
|
+
requires = [ "setuptools>=61",]
|
|
11
|
+
build-backend = "setuptools.build_meta"
|
|
12
|
+
|
|
13
|
+
[tool.setuptools]
|
|
14
|
+
packages = [ "link", "helper", "version", "command", "dac", "utime",]
|
|
15
|
+
|
|
16
|
+
[tool.conda-recipe]
|
|
17
|
+
noarch = true
|
|
18
|
+
build-channels = [ "conda-forge",]
|
|
19
|
+
maintainers = [ "NB-TUDelft",]
|
|
20
|
+
test-imports = []
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.package-data]
|
|
23
|
+
link = [ "*.pyi",]
|
|
24
|
+
helper = [ "*.pyi",]
|
|
25
|
+
version = [ "*.pyi",]
|
|
26
|
+
command = [ "*.pyi",]
|
|
27
|
+
dac = [ "*.pyi",]
|
|
28
|
+
utime = [ "*.pyi",]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
def sleep(seconds: float) -> None: ...
|
|
4
|
+
def sleep_ms(ms: int) -> None: ...
|
|
5
|
+
def sleep_us(us: int) -> None: ...
|
|
6
|
+
|
|
7
|
+
# Include any other native time elements you use so they don't break
|
|
8
|
+
def ticks_ms() -> int: ...
|
|
9
|
+
def ticks_diff(ticks1: int, ticks2: int) -> int: ...
|
|
10
|
+
def ticks_add(ticks1: int, ticks2: int) -> int: ...
|
|
11
|
+
def ticks_us() -> int: ...
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALPACA_FW_VER: str
|