Skip to content

Commit 49b16cb

Browse files
committed
updates the SPI Bus and also adds another user module
After I have been looking at the code in micropython I decided that it's SPI implementation was going to cause problems is used in conjunction with the SPIBus driver. This would make it impossible to use an SPI based touch driver IC. MicroPythons implementation of SPI combined the bus and the device into a single class. It would error if the bus was already initialized and that would lead to no way od being able to attach a touch driver using the same bus. This design is simply not going to work at all so I wrote a new SPI driver for the ESP32. It supports dual, quad and octal modes, all the hardware pins and hosts and the biggest thing is it's not going to pitch a fit if the bus has already been initialized. the module is `spi` and I split the bus and device portions apart so you have `spi.SPI` for the SPI bus and you have `spi.Device` for a device. So you only need to create a single `spi.SPI` instance and then for each device you have attached you create an `spi.Device` instance. Last big improvement of the SPI is it is no longer blocking. It utilizes DMA memory transfers and callbacks to let you know when it has finished transmitting and receiving. You use the device instance to do the sending and receiving and registering the callbacks. I am going to add stub files for the new SPI module as soon as I know everything is compiling properly with this.
1 parent aea0ed4 commit 49b16cb

File tree

14 files changed

+1321
-69
lines changed

14 files changed

+1321
-69
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,9 @@ the calibration by either using a pin that you can check the state of or through
637637
a button in your UI that you provide to the user.
638638

639639
Thank again and enjoy!!
640+
641+
***NOTE***: On ESP32-S3, SPI host 0 and SPI host 1 share a common SPI bus.
642+
The main Flash and PSRAM are connected to the host 0. It is recommended to use
643+
SPI host 2 when connecting an SPI device like a display that is going to utilize
644+
the PSRAM for the frame buffer.
645+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
FILE(GLOB SUBDIRS ABSOLUTE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/*)
3+
FOREACH(SUBDIR ${SUBDIRS})
4+
IF(IS_DIRECTORY ${SUBDIR})
5+
include(${SUBDIR}/micropython.cmake)
6+
ENDIF()
7+
ENDFOREACH()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Create an INTERFACE library for our C module.
2+
3+
4+
add_library(usermod_nvs INTERFACE)
5+
6+
set(NVS_INCLUDES)
7+
set(NVS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/nvs.c)
8+
9+
# gets nvs_flash include paths
10+
idf_component_get_property(NVS_FLASH_INCLUDES nvs_flash INCLUDE_DIRS)
11+
idf_component_get_property(NVS_FLASH_DIR nvs_flash COMPONENT_DIR)
12+
13+
# sets the include paths into INCLUDES variable
14+
if(NVS_FLASH_INCLUDES)
15+
list(TRANSFORM NVS_FLASH_INCLUDES PREPEND ${NVS_FLASH_DIR}/)
16+
list(APPEND NVS_INCLUDES ${NVS_FLASH_INCLUDES})
17+
endif()
18+
19+
# Add our source files to the lib
20+
target_sources(usermod_nvs INTERFACE ${NVS_SOURCES})
21+
22+
# Add include directories.
23+
target_include_directories(usermod_nvs INTERFACE ${NVS_INCLUDES})
24+
25+
# Link our INTERFACE library to the usermod target.
26+
target_link_libraries(usermod INTERFACE usermod_nvs)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "py/runtime.h"
2+
#include "py/stream.h"
3+
#include "py/mphal.h"
4+
#include "mphalport.h"
5+
6+
#include "driver/spi_master.h"
7+
#include "driver/spi_common.h"
8+
#include "soc/spi_pins.h"
9+
10+
#ifndef __ESP32_SPI_H__
11+
#define __ESP32_SPI_H__
12+
13+
14+
typedef struct _esp32_hw_spi_dev_obj_t esp32_hw_spi_dev_obj_t;
15+
typedef struct _esp32_hw_spi_bus_obj_t esp32_hw_spi_bus_obj_t;
16+
17+
typedef struct {
18+
spi_transaction_t base;
19+
bool trans_done;
20+
} esp32_spi_trans_descriptor_t;
21+
22+
23+
struct _esp32_hw_spi_dev_obj_t{
24+
spi_device_interface_config_t devcfg;
25+
esp32_hw_spi_bus_obj_t *spi_bus;
26+
uint8_t bits;
27+
size_t max_transfer_sz;
28+
spi_device_handle_t spi_dev;
29+
30+
mp_obj_t trans_start_cb; // User register's callback, invoked when data trans starts
31+
mp_obj_t trans_start_user_data; // User's private data, passed directly to callback trans_start_cb
32+
33+
mp_obj_t trans_end_cb; // User register's callback, invoked when data trans end
34+
mp_obj_t trans_end_user_data; // User's private data, passed directly to callback trans_end_cb
35+
36+
size_t num_trans_inflight; // Number of transactions that are undergoing (the descriptor not recycled yet)
37+
size_t trans_pool_count; // Size of transaction queue
38+
esp32_spi_trans_descriptor_t trans_pool[]; // Transaction pool
39+
};
40+
41+
struct _esp32_hw_spi_bus_obj_t{
42+
mp_obj_base_t base;
43+
spi_host_device_t host;
44+
spi_bus_config_t buscfg;
45+
bool octal_mode; // Indicates whether the transmitting is enabled with octal mode (8 data lines)
46+
47+
enum {
48+
MACHINE_HW_SPI_STATE_NONE,
49+
MACHINE_HW_SPI_STATE_INIT,
50+
MACHINE_HW_SPI_STATE_DEINIT
51+
} state;
52+
53+
};
54+
55+
typedef struct _esp32_hw_spi_default_pins_t{
56+
int8_t mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
57+
int8_t miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
58+
int8_t sclk_io_num; ///< GPIO pin for SPI Clock signal, or -1 if not used.
59+
int8_t quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal, or -1 if not used.
60+
int8_t quadhd_io_num; ///< GPIO pin for HD (Hold) signal, or -1 if not used.
61+
int8_t data4_io_num; ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used.
62+
int8_t data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
63+
int8_t data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
64+
int8_t data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
65+
int8_t cs_io_num
66+
} esp32_hw_spi_default_pins_t;
67+
68+
extern const mp_obj_type_t esp32_hw_spi_bus_type;
69+
extern const mp_obj_type_t esp32_hw_spi_dev_type;
70+
71+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Create an INTERFACE library for our C module.
2+
add_library(usermod_spi INTERFACE)
3+
4+
set(SPI_INCLUDES)
5+
set(SPI_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/spi.c)
6+
7+
# gets driver include paths
8+
idf_component_get_property(DRIVER_INCLUDES driver INCLUDE_DIRS)
9+
idf_component_get_property(DRIVER_DIR driver COMPONENT_DIR)
10+
11+
# sets the include paths into INCLUDES variable
12+
if(DRIVER_INCLUDES)
13+
list(TRANSFORM DRIVER_INCLUDES PREPEND ${DRIVER_DIR}/)
14+
list(APPEND SPI_INCLUDES ${DRIVER_INCLUDES})
15+
endif()
16+
17+
# Add our source files to the lib
18+
target_sources(usermod_spi INTERFACE ${SPI_SOURCES})
19+
20+
# Add include directories.
21+
target_include_directories(usermod_spi INTERFACE ${SPI_INCLUDES})
22+
23+
# Link our INTERFACE library to the usermod target.
24+
target_link_libraries(usermod INTERFACE usermod_spi)

0 commit comments

Comments
 (0)