Skip to content

Commit ed6e81d

Browse files
committed
Switch SPI to polling DMA and enable displayio
1 parent 496e16d commit ed6e81d

File tree

14 files changed

+183
-60
lines changed

14 files changed

+183
-60
lines changed

ports/esp32s2/background.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ void run_background_tasks(void) {
5454
running_background_tasks = true;
5555
filesystem_background();
5656

57-
// #if CIRCUITPY_DISPLAYIO
58-
// displayio_background();
59-
// #endif
57+
#if CIRCUITPY_DISPLAYIO
58+
displayio_background();
59+
#endif
6060
running_background_tasks = false;
6161

6262
assert_heap_ok();

ports/esp32s2/boards/espressif_saola_1_wrover/board.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030

3131
void board_init(void) {
3232
// USB
33-
never_reset_pin(&pin_GPIO19);
34-
never_reset_pin(&pin_GPIO20);
33+
common_hal_never_reset_pin(&pin_GPIO19);
34+
common_hal_never_reset_pin(&pin_GPIO20);
3535

3636
// Debug UART
37-
never_reset_pin(&pin_GPIO43);
38-
never_reset_pin(&pin_GPIO44);
37+
common_hal_never_reset_pin(&pin_GPIO43);
38+
common_hal_never_reset_pin(&pin_GPIO44);
3939
}
4040

4141
bool board_requests_safe_mode(void) {

ports/esp32s2/common-hal/busio/I2C.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "driver/i2c.h"
3232

3333
#include "shared-bindings/microcontroller/__init__.h"
34+
#include "shared-bindings/microcontroller/Pin.h"
3435
#include "supervisor/shared/translate.h"
3536

3637
typedef enum {
@@ -217,6 +218,6 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
217218
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
218219
never_reset_i2c(self->i2c_num);
219220

220-
never_reset_pin(self->scl_pin);
221-
never_reset_pin(self->sda_pin);
221+
common_hal_never_reset_pin(self->scl_pin);
222+
common_hal_never_reset_pin(self->sda_pin);
222223
}

ports/esp32s2/common-hal/busio/SPI.c

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "py/runtime.h"
3030

3131
#include "boards/board.h"
32-
#include "common-hal/microcontroller/Pin.h"
32+
#include "shared-bindings/microcontroller/Pin.h"
3333
#include "supervisor/shared/rgb_led_status.h"
3434

3535
#include "esp_log.h"
@@ -101,7 +101,8 @@ static bool spi_bus_is_free(spi_host_device_t host_id) {
101101
}
102102

103103
static void spi_interrupt_handler(void *arg) {
104-
// busio_spi_obj_t *self = arg;
104+
busio_spi_obj_t *self = arg;
105+
ESP_LOGE(TAG, "SPI interrupt %p", self);
105106
}
106107

107108
// The interrupt may get invoked by the bus lock.
@@ -148,7 +149,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
148149
mp_raise_ValueError(translate("All SPI peripherals are in use"));
149150
}
150151

151-
esp_err_t result = spi_bus_initialize(host_id, &bus_config, 0 /* dma channel */);
152+
esp_err_t result = spi_bus_initialize(host_id, &bus_config, host_id /* dma channel */);
152153
if (result == ESP_ERR_NO_MEM) {
153154
mp_raise_msg(&mp_type_MemoryError, translate("ESP-IDF memory allocation failed"));
154155
} else if (result == ESP_ERR_INVALID_ARG) {
@@ -183,34 +184,35 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
183184
spi_bus_lock_set_bg_control(spi_bus_get_attr(host_id)->lock, spi_bus_intr_enable, spi_bus_intr_disable, self);
184185

185186
spi_hal_context_t* hal = &self->hal_context;
186-
hal->hw = NULL; // Set by spi_hal_init
187-
hal->dmadesc_tx = NULL;
188-
hal->dmadesc_rx = NULL;
189-
hal->dmadesc_n = 0;
187+
188+
// spi_hal_init clears the given hal context so set everything after.
189+
spi_hal_init(hal, host_id);
190+
hal->dmadesc_tx = &self->tx_dma;
191+
hal->dmadesc_rx = &self->rx_dma;
192+
hal->dmadesc_n = 1;
190193

191194
// We don't use native CS.
192-
hal->cs_setup = 0;
193-
hal->cs_hold = 0;
194-
hal->cs_pin_id = 0;
195+
// hal->cs_setup = 0;
196+
// hal->cs_hold = 0;
197+
// hal->cs_pin_id = 0;
195198

196199
hal->sio = 1;
197-
hal->half_duplex = 0;
198-
hal->tx_lsbfirst = 0;
199-
hal->rx_lsbfirst = 0;
200-
hal->dma_enabled = 0;
200+
// hal->half_duplex = 0;
201+
// hal->tx_lsbfirst = 0;
202+
// hal->rx_lsbfirst = 0;
203+
hal->dma_enabled = 1;
201204
hal->no_compensate = 1;
202205
// Ignore CS bits
203206

204207
// We don't use cmd, addr or dummy bits.
205-
hal->cmd = 0;
206-
hal->cmd_bits = 0;
207-
hal->addr_bits = 0;
208-
hal->dummy_bits = 0;
209-
hal->addr = 0;
208+
// hal->cmd = 0;
209+
// hal->cmd_bits = 0;
210+
// hal->addr_bits = 0;
211+
// hal->dummy_bits = 0;
212+
// hal->addr = 0;
210213

211214
hal->io_mode = SPI_LL_IO_MODE_NORMAL;
212215

213-
spi_hal_init(hal, host_id);
214216
// This must be set after spi_hal_init.
215217
hal->timing_conf = &self->timing_conf;
216218
if (hal->hw == NULL) {
@@ -223,9 +225,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
223225
void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
224226
spi_never_reset[self->host_id] = true;
225227

226-
never_reset_pin(self->clock_pin);
227-
never_reset_pin(self->MOSI_pin);
228-
never_reset_pin(self->MISO_pin);
228+
common_hal_never_reset_pin(self->clock_pin);
229+
common_hal_never_reset_pin(self->MOSI_pin);
230+
common_hal_never_reset_pin(self->MISO_pin);
229231
}
230232

231233
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
@@ -322,17 +324,29 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou
322324
}
323325

324326
spi_hal_context_t* hal = &self->hal_context;
325-
hal->tx_bitlen = len * self->bits;
326-
hal->rx_bitlen = len * self->bits;
327-
hal->send_buffer = (uint8_t*) data_out;
328-
hal->rcv_buffer = data_in;
329-
330-
spi_hal_setup_trans(hal);
331-
spi_hal_prepare_data(hal);
332-
spi_hal_user_start(hal);
333-
if (len >= SOC_SPI_MAXIMUM_BUFFER_SIZE && false) {
334-
// Set up the interrupt and wait on the lock.
335-
} else {
327+
hal->send_buffer = NULL;
328+
hal->rcv_buffer = NULL;
329+
// This rounds up.
330+
size_t dma_count = (len + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC;
331+
for (size_t i = 0; i < dma_count; i++) {
332+
size_t offset = LLDESC_MAX_NUM_PER_DESC * i;
333+
size_t dma_len = len - offset;
334+
if (dma_len > LLDESC_MAX_NUM_PER_DESC) {
335+
dma_len = LLDESC_MAX_NUM_PER_DESC;
336+
}
337+
hal->tx_bitlen = dma_len * self->bits;
338+
hal->rx_bitlen = dma_len * self->bits;
339+
if (data_out != NULL) {
340+
hal->send_buffer = (uint8_t*) data_out + offset;
341+
}
342+
if (data_in != NULL) {
343+
hal->rcv_buffer = data_in + offset;
344+
}
345+
346+
spi_hal_setup_trans(hal);
347+
spi_hal_prepare_data(hal);
348+
spi_hal_user_start(hal);
349+
// TODO: Switch to waiting on a lock that is given by an interrupt.
336350
while (!spi_hal_usr_is_done(hal)) {
337351
RUN_BACKGROUND_TASKS;
338352
}

ports/esp32s2/common-hal/busio/SPI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ typedef struct {
4444
spi_hal_context_t hal_context;
4545
spi_hal_timing_conf_t timing_conf;
4646
intr_handle_t interrupt;
47+
// IDF allocates these in DMA accessible memory so they may need to move when
48+
// we use external RAM for CircuitPython.
49+
lldesc_t tx_dma;
50+
lldesc_t rx_dma;
4751
uint32_t target_frequency;
4852
int32_t real_frequency;
4953
uint8_t polarity;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "shared-bindings/displayio/ParallelBus.h"
28+
29+
#include <stdint.h>
30+
31+
#include "common-hal/microcontroller/Pin.h"
32+
#include "py/runtime.h"
33+
#include "shared-bindings/digitalio/DigitalInOut.h"
34+
#include "shared-bindings/microcontroller/__init__.h"
35+
36+
void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self,
37+
const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select,
38+
const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) {
39+
40+
mp_raise_NotImplementedError(translate("ParallelBus not yet supported"));
41+
}
42+
43+
void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) {
44+
45+
}
46+
47+
bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
48+
return false;
49+
}
50+
51+
bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
52+
return false;
53+
}
54+
55+
bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
56+
57+
return false;
58+
}
59+
60+
void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
61+
62+
}
63+
64+
void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) {
65+
66+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
28+
#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
29+
30+
#include "common-hal/digitalio/DigitalInOut.h"
31+
32+
typedef struct {
33+
mp_obj_base_t base;
34+
} displayio_parallelbus_obj_t;
35+
36+
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void never_reset_pin_number(gpio_num_t pin_number) {
4242
never_reset_pins[pin_number / 32] |= 1 << pin_number % 32;
4343
}
4444

45-
void never_reset_pin(const mcu_pin_obj_t* pin) {
45+
void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
4646
never_reset_pin_number(pin->number);
4747
}
4848

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,5 @@ void common_hal_reset_pin(const mcu_pin_obj_t* pin);
4242
void claim_pin(const mcu_pin_obj_t* pin);
4343
bool pin_number_is_free(gpio_num_t pin_number);
4444
void never_reset_pin_number(gpio_num_t pin_number);
45-
void never_reset_pin(const mcu_pin_obj_t* pin);
4645

4746
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PIN_H

ports/esp32s2/modules/wroom.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828

2929
void never_reset_module_internal_pins(void) {
3030
// SPI Flash
31-
never_reset_pin(&pin_GPIO27);
32-
never_reset_pin(&pin_GPIO28);
33-
never_reset_pin(&pin_GPIO29);
34-
never_reset_pin(&pin_GPIO30);
35-
never_reset_pin(&pin_GPIO31);
36-
never_reset_pin(&pin_GPIO32);
31+
common_hal_never_reset_pin(&pin_GPIO27);
32+
common_hal_never_reset_pin(&pin_GPIO28);
33+
common_hal_never_reset_pin(&pin_GPIO29);
34+
common_hal_never_reset_pin(&pin_GPIO30);
35+
common_hal_never_reset_pin(&pin_GPIO31);
36+
common_hal_never_reset_pin(&pin_GPIO32);
3737
}

0 commit comments

Comments
 (0)