Skip to content

Commit 79f496f

Browse files
U-ANALOG\BHurstBrandon-Hurst
authored andcommitted
-Added USB via tinyUSB. Still need to test/debug before REPL is ready. - Enabled USB-based modules & dependencies in mpconfigport.mk
1 parent b1ca548 commit 79f496f

8 files changed

Lines changed: 160 additions & 49 deletions

File tree

ports/analog/Makefile

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,30 @@ else
166166
COPT += -O0 #opt completely off to start
167167
endif
168168

169-
170169
# TinyUSB CFLAGS
170+
ifeq ($(CIRCUITPY_TINYUSB),1)
171171
CFLAGS += \
172172
-DCFG_TUSB_MCU=OPT_MCU_$(MCU_VARIANT_UPPER) \
173173
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED \
174+
-DCFG_TUSB_OS=OPT_OS_NONE \
175+
-DCFG_TUD_TASK_QUEUE_SZ=32
174176

175-
# TODO: Add for TinyUSB once our PR goes through for MAX32 devices
176-
# Add TinyUSB
177+
# Add TinyUSB sources
177178
INC += -I../../lib/tinyusb/src
178179
INC += -I../../supervisor/shared/usb
179180
SRC_C += lib/tinyusb/src/portable/mentor/musb/dcd_musb.c
181+
endif
182+
183+
ifeq ($(CIRCUITPY_USB_DEVICE),1)
184+
CFLAGS += \
185+
-DCFG_TUD_CDC_RX_BUFSIZE=1024 \
186+
-DCFG_TUD_CDC_TX_BUFSIZE=1024 \
187+
-DCFG_TUD_MSC_BUFSIZE=4096 \
188+
-DCFG_TUD_MIDI_RX_BUFSIZE=128 \
189+
-DCFG_TUD_MIDI_TX_BUFSIZE=128 \
190+
-DCFG_TUD_VENDOR_RX_BUFSIZE=128 \
191+
-DCFG_TUD_VENDOR_TX_BUFSIZE=128
192+
endif
180193

181194
SRC_C += \
182195
boards/$(BOARD)/board.c \

ports/analog/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ This port brings CircuitPython to ADI's "MAX32" series of microcontrollers. Thes
99
- **`linking/:`** Linkerfiles customized for CircuitPython. These are distinct from the linkerfiles used in MSDK as they adopt the structure required by CircuitPython. They may also omit unused features and memory sections, e.g. Mailboxes, RISC-V Flash, & Hyperbus RAM for MAX32690.
1010
- **`msdk:/`** SDK for MAX32 devices. More info on our GitHub: [Analog Devices MSDK GitHub](https://github.com/analogdevicesinc/msdk)
1111
- **`peripherals:/`** Helper files for peripherals such as clocks, gpio, etc. These files tend to be specific to vendor SDKs and provide some useful functions for the common-hal interfaces.
12-
- **`supervisor/:`** Implementation files for the CircuitPython supervisor. This includes port setup, usb, and a filesystem on a storage medium such as SD Card/eMMC, QSPI Flash, or internal flash memory. Currently the internal flash is used.
12+
- **`supervisor/:`** Implementation files for the CircuitPython supervisor. This includes port setup, usb, and a filesystem on a storage medium such as SD Card/eMMC, QSPI Flash, or internal flash memory. Currently the internal flash is used. This folder is the most important part of a port's core functionality for CircuitPython.
13+
- **`supervisor/port.c:`** Port-specific startup code including clock initialization, console startup, etc.
1314

1415
- `. :` Build system and high-level interface to the CircuitPython core for the ADI port.
1516

ports/analog/boards/APARD/board.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,21 @@ const int num_leds = (sizeof(led_pin) / sizeof(mxc_gpio_cfg_t));
3232
// way.
3333
// bool board_requests_safe_mode(void);
3434

35+
volatile uint32_t system_ticks = 0;
36+
37+
void SysTick_Handler(void) {
38+
system_ticks++;
39+
}
40+
41+
uint32_t board_millis(void) {
42+
return system_ticks;
43+
}
44+
3545
// Initializes board related state once on start up.
3646
void board_init(void) {
47+
// 1ms tick timer
48+
SysTick_Config(SystemCoreClock / 1000);\
49+
3750
// Enable GPIO (enables clocks + common init for ports)
3851
for (int i = 0; i < MXC_CFG_GPIO_INSTANCES; i++){
3952
MXC_GPIO_Init(0x1 << i);

ports/analog/boards/APARD/mpconfigboard.mk

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ INTERNAL_FLASH_FILESYSTEM = 1
88
# FLASH: 0x10000000 to 0x10300000 (ARM)
99
# SRAM: 0x20000000 to 0x20100000
1010

11-
USB_PRODUCT = "MAX32690 APARD"
12-
USB_MANUFACTURER = "Analog Devices, Inc."
11+
USB_MANUFACTURER="Analog Devices, Inc."
12+
USB_PRODUCT="MAX32690 APARD"
13+
14+
# Use 0x0456 for Analog Devices, Inc.; 0B6A for Maxim
15+
USB_VID=0x0456
16+
# USB_VID=0x0B6A
17+
USB_PID=0x003C
1318

1419
# NOTE: Not implementing external flash for now
1520
# CFLAGS+=-DEXT_FLASH_MX25

ports/analog/common-hal/microcontroller/Pin.c

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,104 @@
88
#include "mxc_sys.h"
99
#include "max32690.h"
1010
#include "gpio.h"
11+
#include "gpio_regs.h"
12+
13+
// Structs to represent GPIO ports & valid pins/pads
14+
#ifdef MAX32690
15+
// todo: special constraints are applied to GPIO4 for MAX32690. Tend to these later (low prior)
16+
static mxc_gpio_regs_t* ports[NUM_GPIO_PORTS] = { MXC_GPIO0, MXC_GPIO1, MXC_GPIO2, MXC_GPIO3};
17+
#endif
18+
19+
static uint32_t claimed_pins[NUM_GPIO_PORTS];
20+
static uint32_t never_reset_pins[NUM_GPIO_PORTS];
21+
22+
#define INVALID_PIN 0xFF // id for invalid pin
1123

1224
void reset_all_pins(void) {
13-
// todo: this is not a good method for this long-term
14-
// Pins should be individually reset to account for never_reset pins like SWD
25+
// reset all pins except for never_reset_pins
1526
for (int i = 0; i < NUM_GPIO_PORTS; i++) {
16-
MXC_GPIO_Reset(i);
27+
for (int j = 0; j < 32; j++) {
28+
if (!(never_reset_pins[i] & (1 << j))) {
29+
reset_pin_number(i, j);
30+
}
31+
}
32+
// set claimed pins to never_reset pins
33+
claimed_pins[i] = never_reset_pins[i];
1734
}
1835
}
1936

20-
// todo: Implement
21-
void reset_pin_number(uint8_t pin) {
22-
}
37+
void reset_pin_number(uint8_t pin_port, uint8_t pin_pad) {
38+
if (pin_port == INVALID_PIN || pin_port > NUM_GPIO_PORTS) {
39+
return;
40+
}
2341

24-
// todo: Implement
25-
void claim_pin(const mcu_pin_obj_t *pin) {
26-
return;
27-
}
42+
uint32_t mask = 1 << (pin_pad);
2843

29-
// todo: Implement
30-
bool pin_number_is_free(uint8_t pin_number) {
31-
return true;
32-
}
44+
/** START: RESET LOGIC for GPIOs */
45+
// Switch to I/O mode first
46+
ports[pin_port]->en0_set = mask;
47+
48+
// set GPIO configuration enable bits to I/O
49+
ports[pin_port]->en0_clr = mask;
50+
ports[pin_port]->en1_clr = mask;
51+
ports[pin_port]->en2_clr = mask;
52+
53+
// enable input mode GPIOn_INEN.pin = 1
54+
ports[pin_port]->inen |= mask;
55+
56+
// High Impedance mode enable (GPIOn_PADCTRL1 = 0, _PADCTRL0 = 0), pu/pd disable
57+
ports[pin_port]->padctrl0 &= ~mask;
58+
ports[pin_port]->padctrl1 &= ~mask;
3359

60+
// Output mode disable GPIOn_OUTEN = 0
61+
ports[pin_port]->outen |= mask;
3462

35-
// todo: Implement
36-
void never_reset_pin_number(uint8_t pin_number) {
37-
return;
63+
// Interrupt disable GPIOn_INTEN = 0
64+
ports[pin_port]->inten &= ~mask;
65+
/** END: RESET LOGIC for GPIOs */
3866
}
3967

40-
//todo: implement
4168
uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) {
42-
return 0;
69+
if (pin == NULL) {
70+
return INVALID_PIN;
71+
}
72+
73+
// most max32 gpio ports have 32 pins
74+
// todo: create a struct to encode # of pins for each port, since some GPIO ports differ
75+
return pin->port * 32 + pin->pad;
4376
}
4477

45-
// todo: implement
4678
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
47-
return true;
79+
if (pin == NULL) {
80+
return true;
81+
}
82+
return !(claimed_pins[pin->port] & (pin->pad));
4883
}
4984

5085
void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) {
86+
if ((pin != NULL) && (pin->pad != INVALID_PIN)) {
87+
never_reset_pins[pin->port] |= (1 << pin->pad);
88+
89+
// any never reset pin must also be claimed
90+
claimed_pins[pin->port] |= (1 << pin->pad);
91+
}
5192
}
5293

5394
void common_hal_reset_pin(const mcu_pin_obj_t *pin) {
54-
}
95+
if (pin == NULL) {
96+
return;
97+
}
5598

56-
void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
99+
reset_pin_number(pin->port, pin->pad);
57100
}
58101

59-
void common_hal_mcu_pin_claim_number(uint8_t pin_no) {
102+
void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
103+
if (pin == NULL) {
104+
return;
105+
}
106+
claimed_pins[pin->port] |= (1 << pin->pad);
60107
}
61108

62109
void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
110+
reset_pin_number(pin_no / 32, pin_no & 32);
63111
}

ports/analog/common-hal/microcontroller/Pin.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,4 @@
88
void reset_all_pins(void);
99
// reset_pin_number takes the pin number instead of the pointer so that objects don't
1010
// need to store a full pointer.
11-
void reset_pin_number(uint8_t pin);
12-
void claim_pin(const mcu_pin_obj_t *pin);
13-
bool pin_number_is_free(uint8_t pin_number);
14-
void never_reset_pin_number(uint8_t pin_number);
11+
void reset_pin_number(uint8_t pin_port, uint8_t pin_pad);

ports/analog/mpconfigport.mk

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,27 @@ INTERNAL_FLASH_FILESYSTEM = 1
1515
SPI_FLASH_FILESYSTEM = 0
1616
QSPI_FLASH_FILESYSTEM = 0
1717

18-
# TODO: TEST filesystem & general bringup!
18+
# TODO: Test/Debug fs & general bringup
1919
DISABLE_FILESYSTEM = 0
2020

21+
# TODO: Test/Debug TinyUSB!
22+
# Builds clean; need to test
23+
CIRCUITPY_TINYUSB = 1
24+
CIRCUITPY_USB_DEVICE ?= 1
25+
CIRCUITPY_USB_CDC ?= 1
26+
CIRCUITPY_USB_HID ?= 0
27+
CIRCUITPY_USB_MIDI ?= 0
28+
2129
####################################################################################
2230
# Suggested config for first-time porting
2331
####################################################################################
2432
# These modules are implemented in ports/<port>/common-hal:
2533

26-
# Typically the first module to create
27-
CIRCUITPY_MICROCONTROLLER ?= 1
2834
# Typically the second module to create
2935
CIRCUITPY_DIGITALIO ?= 0
3036

3137
# Plan to implement
3238
CIRCUITPY_BUSIO ?= 0
33-
CIRCUITPY_OS ?= 1
3439
CIRCUITPY_RTC ?= 0
3540

3641
# Other modules (may or may not implement):
@@ -58,17 +63,10 @@ CIRCUITPY_BITBANGIO ?= 0
5863
CIRCUITPY_PIXELBUF ?= 0
5964
# Requires OS
6065
CIRCUITPY_RANDOM ?= 0
61-
# Requires OS, filesystem
62-
CIRCUITPY_STORAGE ?= 0
6366
# Requires Microcontroller
6467
CIRCUITPY_TOUCHIO ?= 0
6568
# Requires UART
6669
CIRCUITPY_CONSOLE_UART ?= 0
67-
# Requires USB
68-
CIRCUITPY_USB_DEVICE ?= 0
69-
CIRCUITPY_USB_CDC ?= 0
70-
CIRCUITPY_USB_HID ?= 0
71-
CIRCUITPY_USB_MIDI ?= 0
7270
# Does nothing without I2C
7371
CIRCUITPY_REQUIRE_I2C_PULLUPS = 0
7472

@@ -83,7 +81,3 @@ CIRCUITPY_ULAB = 1
8381
CIRCUITPY_BLEIO_HCI = 0
8482
CIRCUITPY_KEYPAD = 0
8583
CIRCUITPY_BUSDEVICE = 0
86-
87-
# TinyUSB will be added later.
88-
CIRCUITPY_TINYUSB = 0
89-
CIRCUITPY_PYUSB = 0

ports/analog/supervisor/usb.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
#include "supervisor/usb.h"
3+
#include "common-hal/microcontroller/Pin.h"
4+
5+
#include "py/mpconfig.h"
6+
7+
#include "lib/tinyusb/src/device/usbd.h"
8+
9+
// max32 includes
10+
#include "mxc_sys.h"
11+
#include "gcr_regs.h"
12+
#include "mcr_regs.h"
13+
14+
void init_usb_hardware(void) {
15+
// USB GPIOs are non-configurable on MAX32 devices
16+
// No need to add them to the never_reset list for mcu/Pin API.
17+
18+
// 1 ms SysTick initialized in board.c
19+
// todo: consider moving SysTick initialization here?
20+
21+
// Enable requisite clocks & power for USB
22+
MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO);
23+
MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN;
24+
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
25+
MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB);
26+
27+
// Supervisor calls TinyUSB's dcd_init,
28+
// which initializes the USB PHY.
29+
// Dep. on CIRCUITPY_TINYUSB and CIRCUITPY_USB_DEVICE
30+
31+
// Interrupt enables are left to TUSB depending on the device class
32+
// todo: confirm with testing!
33+
}
34+
35+
void USB_IRQHandler(void)
36+
{
37+
// Schedules USB background callback
38+
// appropriate to a given device class via TinyUSB lib
39+
usb_irq_handler(0);
40+
}

0 commit comments

Comments
 (0)