ESP32S3系列 | 您所在的位置:网站首页 › host和device区别 › ESP32S3系列 |
一、目的
SPI是一种串行同步接口,可用于与外围设备进行通信。 ESP32S3自带4个SPI外设,其中SPI0/SPI1内部专用,共用一组信号线,通过一个仲裁器访问外部Flash和PSRAM;SPI2/3各自使用一组独立的信号线;开发者可以使用SPI2/3控制外部SPI从设备(Slave device);其中SPI2作为主设备有6个片选,数据线最多可以有八根,SPI3作为主设备有3个片选,数据线最多可以有四根。SPI2/3既可以作为主机使用,也可以作为从机使用。 本篇主要介绍SPI主机驱动的基本知识,包括标准SPI(MISO/MOSI)/Dual SPI/Quad SPI以及Octal SPI的配置和使用。 关于标准SPI/Dual SPI/Quad SPI以及Octal SPI的区别请阅读《理解SPI/Dual SPI/Quad SPI/QPI之间的区别》。 关于SPI2/3作为从机使用的知识点会在后续博文中详细介绍。 为了方便开发者使用SPI外设,ESP-IDF SDK中将SPI外设抽象为BUS(总线),一条总线上只有一个主设备,但是可以挂接多个从设备,每个从设备各自有独立的一条片选线(CS),其他信号线共用;片选线用于选中设备进行通信。 ![]() 总线框图 上图中slave A和B共用一组信号线,使用的是标准SPI模式;每个设备有自己独立的片选控制线;某个时刻只能控制一个设备,要么控制A,要么控制B;A和B分时使用SPI总线。 如果觉得博客写得不错,或对你有帮助,接受打赏哦 二、介绍 参考资料SPI Master Driver - ESP32-S3 - — ESP-IDF Programming Guide latest documentation (espressif.com) SPI外设框图SPI即串行同步接口 ![]() 其中FSPI即SPI2,SPI2可以通过IOMUX或者GPIO Matrix进行引脚配置,SPI3只能通过GPIO Matrix进行引脚配置。 SPI2/3都支持DMA传输。 全双工和半双工区别模式 说明 全双工 主机与从机之间的发送线和接收线各自独立,发送数据和接收数据同时进行。 半双工 主机和从机只能有一方先发送数据,另一方接收数据。发送数据和接收数据不能同时进行。 四线全双工 四线包括:时钟线、片选线和两条数据线。其中,可使用两条数据线同时发送和接收数据;一根数据线用于发送(MOSI),一根数据线用于接收(MISO) 四线半双工 四线包括:时钟线、片选线和两条数据线。其中,分时使用两条数据线,不可同时使用。 三线半双工 三线包括:时钟线、片选线和一条数据线。使用数据线分时发送和 接收数据。 专业术语术语 描述 Host(主机) 芯片内部的SPI控制器外设,用于主动发起SPI传输 Device(设备) SPI从设备,一条SPI总线可以连接多个从设备;每个设备分时共享信号线;每个设备都有一根独立的片选控制线;当主机需要控制某个设备时,选中对应的片选线即可(一般是拉低CS线) Bus(总线) 多个设备共享的SPI信号线 MOSI(主机输出从机输入) 主机从此信号线输出数据,从设备从此信号线接收数据;在四线/八线模式下作为Data0 MISO(主机输入从机输出) 主机从此信号线接收数据,从设备从此信号线发送数据;在四线/八线模式下作为Data1 SCLK(串行同步时钟) 串行同步时钟,数据的发送接收依赖此信号来同步 CS(片选) 片选信号,每个从设备都有一个片选线 QUADWP(写保护) 写保护信号;在四线/八线模式下作为Data2 QUADHD(保持) 保持信号;在四线/八线模式下作为Data3 DATA4 在八线模式下作为Data4 DATA5 在八线模式下作为Data5 DATA6 在八线模式下作为Data6 DATA7 在八线模式下作为Data7 Assertion 发起SPI传输(一般是拉低片选线),总线进入忙状态 De-assertion SPI传输结束(一般是拉高片选线),总线进入空闲状态 Transaction(传输事务) 一次完整的传输事务:主机拉低从机的 CS 线,开始传输数据,然 后再拉高从机的 CS 线。传输事务为原子操作,即不可打断。 Transfer(传输) SPI 主机与从机完成数据交换的一次完整过程。一次 SPI 传输可以 包含一个或多个 SPI 传输事务。 单次传输 在这种传输模式下,一次SPI传输仅包含一次传输事务。 Launch edge(发射边沿) 数据源寄存器(发送端)在此边沿将数据比特发送至信号线上 Latch edge(锁存边沿) 数据目的寄存器(接收端)在此边沿将数据比特锁存下来 特性支持多线程环境使用 支持CPU控制的传输模式以及DMA控制的传输模式 DMA读写过程用户无感知 自动时分复用(不同时刻对不同设备进行读写) 时钟最高80MHz(主机模式) 注意点同一个设备尽量在一个线程中操作 同一个设备在不同线程中操作需要通过互斥锁进行保护 SPI事务描述每次SPI传输可以包含五个阶段,包括命令、地址、空周期、写、读阶段,每个阶段都是可选的。 阶段 描述 Command(命令) 在此阶段主机可以发送命令字段,长度最多16bit Address(地址) 在此阶段主机可以发送地址字段,长度最多32bit Dummy(空周期) 此阶段用于适配时序要求 Write(写) 此阶段主机发送数据给从设备 Read(读) 此阶段主机读取从设备数据 传输线模式配置(重要) 通过设置传输模式标记可以控制每个阶段的数据线的数目 模式 命令线宽度 地址线宽度 数据线宽度 Transaction Flag Bus IO setting Flag Normal SPI 1 1 1 0 0 Dual Output (DOUT) 1 1 2 SPI_TRANS_MODE_DIO SPICOMMON_BUSFLAG_DUAL Dual I/O (DIO) 1 2 2 SPI_TRANS_MODE_DIO | SPI_TRANS_MULTILINE_ADDR Quad Output (QOUT) 1 1 4 SPI_TRANS_MODE_QIO SPICOMMON_BUSFLAG_QUAD Quad I/O (QIO) 1 4 4 SPI_TRANS_MODE_QIO | SPI_TRANS_MULTILINE_ADDR Octal Output 1 1 8 SPI_TRANS_MODE_OCT SPICOMMON_BUSFLAG_OCTAL OPI 8 8 8 SPI_TRANS_MODE_OCT | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_MULTILINE_CMD 传输标记说明 #define SPI_TRANS_MODE_DIO (1length + 7) / 8, MALLOC_CAP_DMA); if (temp == NULL) goto clean_up; memcpy( temp, send_ptr, (trans_desc->length + 7) / 8 ); send_ptr = temp; } new_desc->buffer_to_send = send_ptr; return ESP_OK; clean_up: uninstall_priv_desc(new_desc); return ESP_ERR_NO_MEM; }在spi_device_queue_trans和spi_device_polling_start函数中通过setup_priv_desc这个函数检查rx_buffer/tx_buffer的属性 ①如果要接收则检查rcv_ptr是否是DMA属性的(在地址区间内)并且rcv_ptr指针的值是否是4字节对齐 ②rcv_ptr不满足dma要求则重新分配 ③如果要发送则检查send_ptr是否是DMA属性的(注意发送的首地址可以不是四字节对齐) SPI外设索引号 /** * @brief Enum with the three SPI peripherals that are software-accessible in it */ typedef enum { //SPI1 can be used as GPSPI only on ESP32 SPI1_HOST=0, ///< SPI1 SPI2_HOST=1, ///< SPI2 SPI3_HOST=2, ///< SPI3 SPI_HOST_MAX, ///< invalid host value } spi_host_device_t;在ESP32S3上可以使用SPI2_HOST和SPI3_HOST SPI总线参数说明 /** * @brief This is a configuration structure for a SPI bus. * * You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the * GPIO matrix to route the signals. An exception is made when all signals either can be routed through * the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds. * * @note Be advised that the slave driver does not use the quadwp/quadhd lines and fields in spi_bus_config_t refering to these lines will be ignored and can thus safely be left uninitialized. */ typedef struct { union { int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used. int data0_io_num; ///< GPIO pin for spi data0 signal in quad/octal mode, or -1 if not used. }; union { int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used. int data1_io_num; ///< GPIO pin for spi data1 signal in quad/octal mode, or -1 if not used. }; int sclk_io_num; ///< GPIO pin for SPI Clock signal, or -1 if not used. union { int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal, or -1 if not used. int data2_io_num; ///< GPIO pin for spi data2 signal in quad/octal mode, or -1 if not used. }; union { int quadhd_io_num; ///< GPIO pin for HD (Hold) signal, or -1 if not used. int data3_io_num; ///< GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used. }; int data4_io_num; ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used. int data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used. int data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used. int data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used. int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled. uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags. int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see * ``esp_intr_alloc.h``. Note that the EDGE, INTRDISABLED attribute are ignored * by the driver. Note that if ESP_INTR_FLAG_IRAM is set, ALL the callbacks of * the driver, and their callee functions, should be put in the IRAM. */ } spi_bus_config_t;各个字段含义: mosi_io_num/data0_io_num:主机输出从机输入或者data0信号线IO引脚编号 miso_io_num/data1_io_num:主机输入从机输出或者data1信号线IO引脚编号 sclk_io_num:时钟信号IO引脚编号 quadwp_io_num/data2_io_num:写保护信号或者data2信号线IO引脚编号 quadhd_io_num/data3_io_num:保持信号或者data3信号线IO引脚编号 data4_io_num:data4信号线IO引脚编号 data5_io_num:data5信号线IO引脚编号 data6_io_num:data6信号线IO引脚编号 data7_io_num:data7信号线IO引脚编号 max_transfer_size:一次SPI传输最大的长度;使能DMA传输时,如果设置为0,则默认限制为4092字节;未使能DMA时,如果设置为0,则默认限制为SOC_SPI_MAXIMUM_BUFFER_SIZE(64字节)。 flags:总线特征标志,具体说明请看下文 intr_flags:中断特征标志,如果设置为ESP_INTR_FLAG_IRAM则驱动中涉及到的回调以及回调调用的函数也要是IRAM属性的 其中数据线根据实际硬件需要设置,如果某些引脚不需要,设置为-1即可。 关于flags字段的说明 #define SPICOMMON_BUSFLAG_SLAVE 0 ///< Initialize I/O in slave mode设置从设备模式,内部使用;通过spi_slave_initialize接口初始化默认为从设备模式 #define SPICOMMON_BUSFLAG_MASTER (18; //End Col High trans[1].tx_data[3]=(320)&0xff; //End Col Low trans[2].tx_data[0]=0x2B; //Page address set trans[3].tx_data[0]=ypos>>8; //Start page high trans[3].tx_data[1]=ypos&0xff; //start page low trans[3].tx_data[2]=(ypos+PARALLEL_LINES)>>8; //end page high trans[3].tx_data[3]=(ypos+PARALLEL_LINES)&0xff; //end page low trans[4].tx_data[0]=0x2C; //memory write trans[5].tx_buffer=linedata; //finally send the line data trans[5].length=320*2*8*PARALLEL_LINES; //Data length, in bits trans[5].flags=0; //undo SPI_TRANS_USE_TXDATA flag //Queue all transactions. for (x=0; x |
CopyRight 2018-2019 实验室设备网 版权所有 |