Skip to content

Commit b80e6f3

Browse files
Update fri3d_2026.py
1 parent 00475e3 commit b80e6f3

File tree

3 files changed

+22
-117
lines changed

3 files changed

+22
-117
lines changed

internal_filesystem/lib/mpos/board/fri3d_2024.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
btn_a = Pin(39, Pin.IN, Pin.PULL_UP) # A
9494
btn_b = Pin(40, Pin.IN, Pin.PULL_UP) # B
9595
btn_start = Pin(0, Pin.IN, Pin.PULL_UP) # START
96-
btn_menu = Pin(45, Pin.IN, Pin.PULL_UP) # START
96+
btn_menu = Pin(45, Pin.IN, Pin.PULL_UP) # MENU
9797

9898
ADC_KEY_MAP = [
9999
{'key': 'UP', 'unit': 1, 'channel': 2, 'min': 3072, 'max': 4096},

internal_filesystem/lib/mpos/board/fri3d_2026.py

Lines changed: 20 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# TODO:
44
# - touch screen / touch pad
5-
# - IMU is different from fri3d_2024 (also address 0x6A instead of 0x6B)
5+
# - IMU (LSM6DSO) is different from fri3d_2024 (and address 0x6A instead of 0x6B) but the API seems the same, except different chip ID (0x6C iso 0x6A)
66
# - I2S audio (communicator) is the same
77
# - headphone jack audio?
88
# - headphone jack microphone?
@@ -12,6 +12,7 @@
1212
# - digital buttons (X,Y,A,B, MENU)
1313
# - buzzer
1414
# - audio DAC emulation using buzzer might be slow or need specific buffered protocol
15+
# - test it on the Waveshare to make sure no syntax / variable errors
1516

1617
from machine import Pin, SPI, SDCard
1718
import st7789
@@ -30,33 +31,20 @@
3031
import mpos.ui
3132
import mpos.ui.focus_direction
3233

33-
34-
# Pin configuration
35-
SPI_BUS = 2
36-
SPI_FREQ = 40000000
37-
#SPI_FREQ = 20000000 # also works but I guess higher is better
38-
LCD_SCLK = 7
39-
LCD_MOSI = 6
40-
LCD_MISO = 8
41-
LCD_DC = 4
42-
LCD_CS = 5
43-
#LCD_BL = 1 # backlight can't be controlled on this hardware
44-
LCD_RST = 48
45-
4634
TFT_HOR_RES=320
4735
TFT_VER_RES=240
4836

4937
spi_bus = machine.SPI.Bus(
50-
host=SPI_BUS,
51-
mosi=LCD_MOSI,
52-
miso=LCD_MISO,
53-
sck=LCD_SCLK
38+
host=2,
39+
mosi=6,
40+
miso=8,
41+
sck=7
5442
)
5543
display_bus = lcd_bus.SPIBus(
5644
spi_bus=spi_bus,
57-
freq=SPI_FREQ,
58-
dc=LCD_DC,
59-
cs=LCD_CS
45+
freq=40000000,
46+
dc=4,
47+
cs=5
6048
)
6149

6250
# lv.color_format_get_size(lv.COLOR_FORMAT.RGB565) = 2 bytes per pixel * 320 * 240 px = 153600 bytes
@@ -84,8 +72,8 @@
8472
color_space=lv.COLOR_FORMAT.RGB565,
8573
color_byte_order=st7789.BYTE_ORDER_BGR,
8674
rgb565_byte_swap=True,
87-
reset_pin=LCD_RST, # doesn't seem needed
88-
reset_state=STATE_LOW # doesn't seem needed
75+
reset_pin=48, # LCD reset: TODO: this is now on the CH32
76+
reset_state=STATE_LOW # TODO: is this correct?
8977
)
9078

9179
mpos.ui.main_display.init()
@@ -96,77 +84,18 @@
9684
# Touch handling:
9785
# touch pad interrupt TP Int is on ESP.IO13
9886
i2c_bus = i2c.I2C.Bus(host=I2C_BUS, scl=TP_SCL, sda=TP_SDA, freq=I2C_FREQ, use_locks=False)
99-
touch_dev = i2c.I2C.Device(bus=i2c_bus, dev_id=TP_ADDR, reg_bits=TP_REGBITS)
87+
touch_dev = i2c.I2C.Device(bus=i2c_bus, dev_id=0x15, reg_bits=TP_REGBITS)
10088
indev=cst816s.CST816S(touch_dev,startup_rotation=lv.DISPLAY_ROTATION._180) # button in top left, good
10189

10290
lv.init()
10391
mpos.ui.main_display.set_rotation(lv.DISPLAY_ROTATION._270) # must be done after initializing display and creating the touch drivers, to ensure proper handling
10492
mpos.ui.main_display.set_params(0x36, bytearray([0x28]))
10593

106-
# Button and joystick handling code:
94+
# Button handling code:
10795
from machine import ADC, Pin
10896
import time
10997

110-
btn_x = Pin(38, Pin.IN, Pin.PULL_UP) # X
111-
btn_y = Pin(41, Pin.IN, Pin.PULL_UP) # Y
112-
btn_a = Pin(39, Pin.IN, Pin.PULL_UP) # A
113-
btn_b = Pin(40, Pin.IN, Pin.PULL_UP) # B
11498
btn_start = Pin(0, Pin.IN, Pin.PULL_UP) # START
115-
btn_menu = Pin(45, Pin.IN, Pin.PULL_UP) # START
116-
117-
ADC_KEY_MAP = [
118-
{'key': 'UP', 'unit': 1, 'channel': 2, 'min': 3072, 'max': 4096},
119-
{'key': 'DOWN', 'unit': 1, 'channel': 2, 'min': 0, 'max': 1024},
120-
{'key': 'RIGHT', 'unit': 1, 'channel': 0, 'min': 3072, 'max': 4096},
121-
{'key': 'LEFT', 'unit': 1, 'channel': 0, 'min': 0, 'max': 1024},
122-
]
123-
124-
# Initialize ADC for the two channels
125-
adc_up_down = ADC(Pin(3)) # ADC1_CHANNEL_2 (GPIO 33)
126-
adc_up_down.atten(ADC.ATTN_11DB) # 0-3.3V range
127-
adc_left_right = ADC(Pin(1)) # ADC1_CHANNEL_0 (GPIO 36)
128-
adc_left_right.atten(ADC.ATTN_11DB) # 0-3.3V range
129-
130-
def read_joystick():
131-
# Read ADC values
132-
val_up_down = adc_up_down.read()
133-
val_left_right = adc_left_right.read()
134-
135-
# Check each key's range
136-
for mapping in ADC_KEY_MAP:
137-
adc_val = val_up_down if mapping['channel'] == 2 else val_left_right
138-
if mapping['min'] <= adc_val <= mapping['max']:
139-
return mapping['key']
140-
return None # No key triggered
141-
142-
# Rotate: UP = 0°, RIGHT = 90°, DOWN = 180°, LEFT = 270°
143-
def read_joystick_angle(threshold=0.1):
144-
# Read ADC values
145-
val_up_down = adc_up_down.read()
146-
val_left_right = adc_left_right.read()
147-
148-
#if time.time() < 60:
149-
# print(f"val_up_down: {val_up_down}")
150-
# print(f"val_left_right: {val_left_right}")
151-
152-
# Normalize to [-1, 1]
153-
x = (val_left_right - 2048) / 2048 # Positive x = RIGHT
154-
y = (val_up_down - 2048) / 2048 # Positive y = UP
155-
#if time.time() < 60:
156-
# print(f"x,y = {x},{y}")
157-
158-
# Check if joystick is near center
159-
magnitude = math.sqrt(x*x + y*y)
160-
#if time.time() < 60:
161-
# print(f"magnitude: {magnitude}")
162-
if magnitude < threshold:
163-
return None # Neutral position
164-
165-
# Calculate angle in degrees with UP = 0°, clockwise
166-
angle_rad = math.atan2(x, y)
167-
angle_deg = math.degrees(angle_rad)
168-
angle_deg = (angle_deg + 360) % 360 # Normalize to [0, 360)
169-
return angle_deg
17099

171100
# Key repeat configuration
172101
# This whole debounce logic is only necessary because LVGL 9.2.2 seems to have an issue where
@@ -186,37 +115,13 @@ def keypad_read_cb(indev, data):
186115
data.continue_reading = False
187116
since_last_repeat = 0
188117

189-
# Check buttons and joystick
118+
# Check buttons
190119
current_key = None
191120
current_time = time.ticks_ms()
192121

193122
# Check buttons
194-
if btn_x.value() == 0:
195-
current_key = lv.KEY.ESC
196-
elif btn_y.value() == 0:
197-
current_key = ord("Y")
198-
elif btn_a.value() == 0:
199-
current_key = lv.KEY.ENTER
200-
elif btn_b.value() == 0:
201-
current_key = ord("B")
202-
elif btn_menu.value() == 0:
203-
current_key = lv.KEY.HOME
204-
elif btn_start.value() == 0:
123+
if btn_start.value() == 0:
205124
current_key = lv.KEY.END
206-
else:
207-
# Check joystick
208-
angle = read_joystick_angle(0.30) # 0.25-0.27 is right on the edge so 0.30 should be good
209-
if angle:
210-
if angle > 45 and angle < 135:
211-
current_key = lv.KEY.RIGHT
212-
elif angle > 135 and angle < 225:
213-
current_key = lv.KEY.DOWN
214-
elif angle > 225 and angle < 315:
215-
current_key = lv.KEY.LEFT
216-
elif angle < 45 or angle > 315:
217-
current_key = lv.KEY.UP
218-
else:
219-
print(f"WARNING: unhandled joystick angle {angle}") # maybe we could also handle diagonals?
220125

221126
# Key repeat logic
222127
if current_key:
@@ -294,7 +199,7 @@ def adc_to_voltage(adc_value):
294199
from machine import PWM, Pin
295200
from mpos import AudioFlinger
296201

297-
# Initialize buzzer: sits on PC14/CC1 of the CH32X035GxUx
202+
# Initialize buzzer: now sits on PC14/CC1 of the CH32X035GxUx so needs custom code
298203
#buzzer = PWM(Pin(46), freq=550, duty=0)
299204

300205
# I2S pin configuration for audio output (DAC) and input (microphone)
@@ -303,16 +208,16 @@ def adc_to_voltage(adc_value):
303208
# See schematics: DAC has BCK=2, WS=47, SD=16; Microphone has SCLK=17, WS=47, DIN=15
304209
i2s_pins = {
305210
# Output (DAC/speaker) pins
306-
'sck': 2, # BCK - Bit Clock for DAC output
211+
'sck': 2, # MCLK / BCK - Bit Clock for DAC output
307212
'ws': 47, # Word Select / LRCLK (shared between DAC and mic)
308213
'sd': 16, # Serial Data OUT (speaker/DAC)
309214
# Input (microphone) pins
310215
'sck_in': 17, # SCLK - Serial Clock for microphone input
311216
'sd_in': 15, # DIN - Serial Data IN (microphone)
312217
}
313218

314-
# Initialize AudioFlinger with I2S and buzzer
315-
#AudioFlinger(i2s_pins=i2s_pins, buzzer_instance=buzzer)
219+
# Initialize AudioFlinger with I2S (buzzer TODO)
220+
AudioFlinger(i2s_pins=i2s_pins)
316221

317222
# === LED HARDWARE ===
318223
import mpos.lights as LightsManager
@@ -323,7 +228,7 @@ def adc_to_voltage(adc_value):
323228
# === SENSOR HARDWARE ===
324229
import mpos.sensor_manager as SensorManager
325230

326-
# Create I2C bus for IMU
231+
# Create I2C bus for IMU (LSM6DSOTR-C / LSM6DSO)
327232
from machine import I2C
328233
imu_i2c = I2C(0, sda=Pin(9), scl=Pin(18))
329234
SensorManager.init(imu_i2c, address=0x6A, mounted_position=SensorManager.FACING_EARTH)

internal_filesystem/lib/mpos/hardware/drivers/wsen_isds.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class Wsen_Isds:
104104
'reg': 0x5E, 'mask': 0b11110111, 'shift_left': 3,
105105
'val_to_bits': {0: 0b00, 1: 0b01}
106106
},
107-
'int1_on_int0': {
107+
'int1_on_int0': { # on the LSM6DSO, this is called "INT2_on_INT1"
108108
'reg': 0x13, 'mask': 0b11011111, 'shift_left': 5,
109109
'val_to_bits': {0: 0b00, 1: 0b01}
110110
},

0 commit comments

Comments
 (0)