Skip to content

Commit f00d424

Browse files
committed
core: pinmux: implement rough solution
While we prepare a cleaner solution, this patch allows back and forth between pinmuxes. Tested on UNO Q with next patch in the series and this sketch void loop() { Serial.begin(115200); Serial.println("helloooooo"); delay(20); Serial.end(); delay(20); pinMode(1, OUTPUT); digitalWrite(1, HIGH); delay(10); digitalWrite(1, LOW); delay(100); analogWrite(1, 33); } Pin 1 correctly prints the string, muxes as GPIo and then produces the required PWM
1 parent 93ad66d commit f00d424

File tree

7 files changed

+36
-0
lines changed

7 files changed

+36
-0
lines changed

cores/arduino/zephyrCommon.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@
77
#include <Arduino.h>
88
#include "zephyrInternal.h"
99

10+
// create an array of arduino_pins with functions to reinitialize pins if needed
11+
static const struct device *pinmux_array[DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios)] = { nullptr };
12+
13+
void _reinit_peripheral_if_needed(pin_size_t pin, const struct device *dev)
14+
{
15+
if (pinmux_array[pin] != dev) {
16+
pinmux_array[pin] = dev;
17+
if (dev != NULL) {
18+
dev->ops.init(dev);
19+
}
20+
}
21+
}
22+
1023
static const struct gpio_dt_spec arduino_pins[] = {
1124
DT_FOREACH_PROP_ELEM_SEP(
1225
DT_PATH(zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
@@ -209,6 +222,7 @@ void yield(void) {
209222
* A high physical level will be interpreted as value 1
210223
*/
211224
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
225+
_reinit_peripheral_if_needed(pinNumber, NULL);
212226
if (pinMode == INPUT) { // input mode
213227
gpio_pin_configure_dt(&arduino_pins[pinNumber], GPIO_INPUT | GPIO_ACTIVE_HIGH);
214228
} else if (pinMode == INPUT_PULLUP) { // input with internal pull-up
@@ -320,6 +334,7 @@ void analogWrite(pin_size_t pinNumber, int value) {
320334
return;
321335
}
322336

337+
_reinit_peripheral_if_needed(pinNumber, arduino_pwm[idx].dev);
323338
value = map(value, 0, 1 << _analog_write_resolution, 0, arduino_pwm[idx].period);
324339

325340
if (((uint32_t)value) > arduino_pwm[idx].period) {
@@ -343,6 +358,9 @@ void analogWrite(enum dacPins dacName, int value) {
343358
return;
344359
}
345360

361+
// TODO: add reverse map to find pin name from DAC* define
362+
// In the meantime, consider A0 == DAC0
363+
_reinit_peripheral_if_needed((pin_size_t)(dacName + A0), dac_dev);
346364
dac_channel_setup(dac_dev, &dac_ch_cfg[dacName]);
347365

348366
const int max_dac_value = 1U << dac_ch_cfg[dacName].resolution;
@@ -393,6 +411,8 @@ int analogRead(pin_size_t pinNumber) {
393411
return -ENOTSUP;
394412
}
395413

414+
_reinit_peripheral_if_needed(pinNumber, arduino_adc[idx].dev);
415+
396416
err = adc_channel_setup(arduino_adc[idx].dev, &arduino_adc[idx].channel_cfg);
397417
if (err < 0) {
398418
return err;

cores/arduino/zephyrInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414

1515
void enableInterrupt(pin_size_t);
1616
void disableInterrupt(pin_size_t);
17+
void _reinit_peripheral_if_needed(pin_size_t pin, const struct device *dev);
1718

1819
#ifdef __cplusplus
1920
} // extern "C"

cores/arduino/zephyrSerial.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ void arduino::ZephyrSerial::begin(unsigned long baud, uint16_t conf) {
5959
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
6060
};
6161

62+
uart->ops.init(uart);
63+
6264
uart_configure(uart, &config);
6365
uart_irq_callback_user_data_set(uart, arduino::ZephyrSerial::IrqDispatch, this);
6466
k_sem_take(&rx.sem, K_FOREVER);

cores/arduino/zephyrSerial.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class ZephyrSerial : public HardwareSerial {
7575
void flush();
7676

7777
void end() {
78+
if (uart->ops.deinit) {
79+
uart->ops.deinit(uart);
80+
}
7881
}
7982

8083
size_t write(const uint8_t *buffer, size_t size);

libraries/SPI/SPI.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,13 @@ void arduino::ZephyrSPI::detachInterrupt() {
115115
}
116116

117117
void arduino::ZephyrSPI::begin() {
118+
spi_dev->ops.init(spi_dev);
118119
}
119120

120121
void arduino::ZephyrSPI::end() {
122+
if (spi_dev->ops.deinit) {
123+
spi_dev->ops.deinit(spi_dev);
124+
}
121125
}
122126

123127
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), spis)

libraries/Wire/Wire.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ arduino::ZephyrI2C::ZephyrI2C(const struct device *i2c) : i2c_dev(i2c), i2c_cfg(
5454
}
5555

5656
void arduino::ZephyrI2C::begin() {
57+
i2c_dev->ops.init(i2c_dev);
5758
}
5859

5960
void arduino::ZephyrI2C::begin(uint8_t slaveAddr) {
@@ -70,6 +71,9 @@ void arduino::ZephyrI2C::end() {
7071
i2c_target_unregister(i2c_dev, &i2c_cfg);
7172
memset(&i2c_cfg, 0, sizeof(i2c_cfg));
7273
}
74+
if (i2c_dev->ops.deinit) {
75+
i2c_dev->ops.deinit(i2c_dev);
76+
}
7377
}
7478

7579
void arduino::ZephyrI2C::setClock(uint32_t freq) {

loader/prj.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ CONFIG_LLEXT_EDK_FORMAT_TAR_ZSTD=y
3030

3131
CONFIG_GPIO=y
3232
CONFIG_PINCTRL=y
33+
CONFIG_PINCTRL_DYNAMIC=y
34+
CONFIG_DEVICE_DEINIT_SUPPORT=y
3335
CONFIG_I2C=y
3436
CONFIG_SPI=y
3537

0 commit comments

Comments
 (0)