-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_hal.py
More file actions
139 lines (107 loc) · 4.99 KB
/
_hal.py
File metadata and controls
139 lines (107 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# This file is part of espzero, automatically synced from
# https://github.com/roboticsware/espzero at revision 24cae2bc1c028458052675181e95f2a08fdf7481.
# Do not edit this file directly — run update_user_libs.py espzero instead.
"""
espzero/_hal.py
Hardware Abstraction Layer (HAL).
All calls to the machine module are routed through this file.
Swapping the board profile is enough to support a new board;
the higher-level _core.py requires no changes.
"""
# ── Global state ───────────────────────────────────────────────
_profile = None # Set by begin() to a BoardProfile instance
_wifi_active = False # True while WiFi is connected; False after disconnect
# ── Profile access ─────────────────────────────────────────────
def get_profile():
if _profile is None:
raise RuntimeError(
"[espzero] Call espzero.begin() before using any espzero class."
)
return _profile
# ── Pin resolution ─────────────────────────────────────────────
def resolve_pin(pin):
"""Convert a string alias or integer pin number to a GPIO integer."""
return get_profile().resolve_pin(pin)
# ── Digital output ─────────────────────────────────────────────
def make_digital_out(pin):
"""Create a digital output Pin object.
Raises RuntimeError if the GPIO is wired to internal flash memory.
"""
from machine import Pin
gpio = resolve_pin(pin)
p = get_profile()
if gpio in p.RESTRICTED_PINS:
raise RuntimeError(
"[espzero] ERROR: GPIO {} is a flash-memory pin on the {} board. "
"Using it as GPIO will corrupt flash and hang the system.".format(
gpio, p.NAME)
)
return Pin(gpio, Pin.OUT)
# ── Digital input ──────────────────────────────────────────────
def make_digital_in(pin, pull_up=False):
"""
Create a digital input Pin object.
Raises RuntimeError if the GPIO is a flash-memory pin.
Prints a warning if the GPIO is a boot-strapping pin.
"""
from machine import Pin
gpio = resolve_pin(pin)
p = get_profile()
if gpio in p.RESTRICTED_PINS:
raise RuntimeError(
"[espzero] ERROR: GPIO {} is a flash-memory pin on the {} board. "
"Using it as GPIO will corrupt flash and hang the system.".format(
gpio, p.NAME)
)
if gpio in p.STRAPPING_PINS:
print(
"[espzero] WARNING: GPIO {} is a strapping pin on the {} board. "
"Attaching a button or switch may cause boot or download-mode "
"issues.".format(gpio, p.NAME)
)
return Pin(gpio, Pin.IN,
Pin.PULL_UP if pull_up else Pin.PULL_DOWN)
# ── PWM ────────────────────────────────────────────────────────
def make_pwm(pin, freq=None):
"""Create a PWM object. Uses the profile default frequency if freq is None."""
from machine import PWM, Pin
p = get_profile()
pwm = PWM(Pin(resolve_pin(pin)))
pwm.freq(freq if freq is not None else p.PWM_DEFAULT_FREQ)
return pwm
def set_duty_u16(pwm_obj, value):
"""
Set PWM duty cycle as a 16-bit value (0–65535).
Falls back to duty(0–1023) on MicroPython < 1.19 where duty_u16() is absent.
"""
try:
pwm_obj.duty_u16(value)
except AttributeError:
# Firmware < 1.19: duty() accepts 0–1023 (10-bit)
pwm_obj.duty(value >> 6)
def get_duty_u16(pwm_obj):
"""Read PWM duty cycle as a 16-bit value. Falls back for older firmware."""
try:
return pwm_obj.duty_u16()
except AttributeError:
return pwm_obj.duty() << 6
# ── ADC ────────────────────────────────────────────────────────
def make_adc(pin):
"""
Create an ADC object.
Prints a warning if WiFi is active and the requested pin belongs to the
ADC2 channel group, which is unusable while WiFi is running on ESP32.
"""
global _wifi_active
p = get_profile()
gpio = resolve_pin(pin)
if _wifi_active and gpio in p.ADC2_PINS:
print(
"[espzero] WARNING: WiFi is active. ADC2 (GPIO {}) cannot be used "
"while WiFi is running. Switch to an ADC1 pin "
"(e.g. GPIO 32-39 on WROOM).".format(gpio)
)
return p.make_adc(gpio)
def adc_read_u16(adc_obj):
"""Read ADC and return a value scaled to 0–65535 (16-bit range)."""
return get_profile().adc_read_u16(adc_obj)