当前位置:网站首页>i.MX - RT1052 SPI和 I2C接口
i.MX - RT1052 SPI和 I2C接口
2022-06-21 11:58:00 【夏沫の浅雨】
写在前面:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
目录
SPI和 I2C协议的分析可以看之前的篇章:UART/USRAT、I2C、SPI通信方式扫盲
一、SPI
1.1 信号线

1.2 架构框图

1.3 传输
- 在以下情况下,LPSPI启动SPI总线传输:
- 数据写入发送 FIFO
- 并置位(或禁用)了HREQ引脚
- 使能了 LPSPI
- 要执行 SPI总线传输,LPSPI使用以下命令中配置的属性: 发送命令寄存器(TCR),并使用时钟配置寄存器(CCR)中的时序参数。
- SPI总线在到达 FRAMESZ配置后传输结束,或者当新的发送命令字位于发送/命令FIFO的顶部时,SPI总线传输结束于字的末尾。
- 仅在下次 LPSPI空闲时(LPSPI完成当前传输并且发送命令寄存器(TCR)为空)时才检查HREQ输入。
循环 FIFO:发送/命令 FIFO还支持循环 FIFO功能,该功能使 LPSPI主设备能够(周期性地)重复一次短的数据传输,该传输可以适合发送/命令 FIFO,而无需其他 FIFO访问。 启用循环 FIFO后,将保存 FIFO读取指针的当前状态,并且状态标志不会更新。 在发送/命令 FIFO被认为是空的并且 LPSPI处于空闲状态之后,FIFO读取指针将用保存的版本恢复,因此在启用循环 FIFO模式时,发送/命令 FIFO的内容不会被永久从 FIFO中拉出。
1.4 时钟环回
1、可以将 LPSPI主器件配置为使用 2个时钟中的 1个来采样输入数据(例如LPSPI_SIN):
- 直接使用 LPSPI_SCK输出时钟
- 或 LPSPI_SCK输出时钟的延迟版本
2、LPSPI_SCK的延迟版本被 LPSPI_SCK引脚输出延迟加上 LPSPI_SCK引脚输入延迟所延迟,并通过设置CFGR1 [SAMPLE]进行配置。
3、启用 LPSPI_SCK的环回版本可以缩短从机输入数据的建立时间。

1.5 Transactional APIs代码
spi总线一般使用 Transactional APIs来操作;具体可以看官方 SDK包里下面路径的例程:
…\ boards\ evkbimxrt1050\ demo_apps\ lpspi_loopback
/*! * @name Transactional * @{ */
/*Transactional APIs*/
/*! * @brief Initializes the LPSPI master handle. * * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a * specified LPSPI instance, call this API once to get the initialized handle. * @param base LPSPI peripheral address. * @param handle LPSPI handle pointer to lpspi_master_handle_t. * @param callback DSPI callback. * @param userData callback function parameter. */
void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base,
lpspi_master_handle_t *handle,
lpspi_master_transfer_callback_t callback,
void *userData);
/*! * @brief LPSPI master transfer data using a polling method. * * This function transfers data using a polling method. This is a blocking function, which does not return until all * transfers have been * completed. * * Note: * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. * For bytesPerFrame greater than 4: * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. * * @param base LPSPI peripheral address. * @param transfer pointer to lpspi_transfer_t structure. * @return status of status_t. */
status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer);
/*! * @brief LPSPI master transfer data using an interrupt method. * * This function transfers data using an interrupt method. This is a non-blocking function, which returns right away. * When all data * is transferred, the callback function is called. * * Note: * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. * For bytesPerFrame greater than 4: * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_master_handle_t structure which stores the transfer state. * @param transfer pointer to lpspi_transfer_t structure. * @return status of status_t. */
status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer);
/*! * @brief Gets the master transfer remaining bytes. * * This function gets the master transfer remaining bytes. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_master_handle_t structure which stores the transfer state. * @param count Number of bytes transferred so far by the non-blocking transaction. * @return status of status_t. */
status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count);
/*! * @brief LPSPI master abort transfer which uses an interrupt method. * * This function aborts a transfer which uses an interrupt method. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_master_handle_t structure which stores the transfer state. */
void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle);
/*! * @brief LPSPI Master IRQ handler function. * * This function processes the LPSPI transmit and receive IRQ. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_master_handle_t structure which stores the transfer state. */
void LPSPI_MasterTransferHandleIRQ(LPSPI_Type *base, lpspi_master_handle_t *handle);
/*! * @brief Initializes the LPSPI slave handle. * * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a * specified LPSPI instance, call this API once to get the initialized handle. * * @param base LPSPI peripheral address. * @param handle LPSPI handle pointer to lpspi_slave_handle_t. * @param callback DSPI callback. * @param userData callback function parameter. */
void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base,
lpspi_slave_handle_t *handle,
lpspi_slave_transfer_callback_t callback,
void *userData);
/*! * @brief LPSPI slave transfer data using an interrupt method. * * This function transfer data using an interrupt method. This is a non-blocking function, which returns right away. * When all data * is transferred, the callback function is called. * * Note: * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. * For bytesPerFrame greater than 4: * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. * @param transfer pointer to lpspi_transfer_t structure. * @return status of status_t. */
status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer);
/*! * @brief Gets the slave transfer remaining bytes. * * This function gets the slave transfer remaining bytes. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. * @param count Number of bytes transferred so far by the non-blocking transaction. * @return status of status_t. */
status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count);
/*! * @brief LPSPI slave aborts a transfer which uses an interrupt method. * * This function aborts a transfer which uses an interrupt method. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. */
void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle);
/*! * @brief LPSPI Slave IRQ handler function. * * This function processes the LPSPI transmit and receives an IRQ. * * @param base LPSPI peripheral address. * @param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. */
void LPSPI_SlaveTransferHandleIRQ(LPSPI_Type *base, lpspi_slave_handle_t *handle);
二、I2C
2.1 信号线

2.2 架构框图

2.3 数据收发
- 发送和接收数据寄存器是双缓冲的,仅分别在从发送和从接收传输期间更新。
- 可以将接收到的从机地址配置为从接收数据寄存器(例如,使用DMA传输数据时)或从地址状态寄存器中读取。
- 可以将发送数据寄存器配置为仅在检测到从发送传输之后请求数据,或者在发送数据寄存器为空时请求新数据。
- 仅当设置了发送数据标志时,才应写入发送数据寄存器。
- 仅当设置了接收数据标志(或设置了地址有效标志且 RXCFG = 1)时,才应读取接收数据寄存器。
- 仅当设置了地址有效标志时,才应读取地址状态寄存器。
2.4 Transactional APIs代码
spi总线一般使用 Transactional APIs来操作;具体可以看官方 SDK包里下面路径的例程:
…\ boards\ evkbimxrt1050\ driver_examples\ lpi2c\ interrupt_b2b_transfer\ master(or slave) Master:
/*! @name Non-blocking */
/*@{*/
/*! * @brief Creates a new handle for the LPI2C master non-blocking APIs. * * The creation of a handle is for use with the non-blocking APIs. Once a handle * is created, there is not a corresponding destroy handle. If the user wants to * terminate a transfer, the LPI2C_MasterTransferAbort() API shall be called. * * * @note The function also enables the NVIC IRQ for the input LPI2C. Need to notice * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to * enable the associated INTMUX IRQ in application. * * @param base The LPI2C peripheral base address. * @param[out] handle Pointer to the LPI2C master driver handle. * @param callback User provided pointer to the asynchronous callback function. * @param userData User provided pointer to the application callback data. */
void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base,
lpi2c_master_handle_t *handle,
lpi2c_master_transfer_callback_t callback,
void *userData);
/*! * @brief Performs a non-blocking transaction on the I2C bus. * * @param base The LPI2C peripheral base address. * @param handle Pointer to the LPI2C master driver handle. * @param transfer The pointer to the transfer descriptor. * @retval kStatus_Success The transaction was started successfully. * @retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking * transaction is already in progress. */
status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base,
lpi2c_master_handle_t *handle,
lpi2c_master_transfer_t *transfer);
/*! * @brief Returns number of bytes transferred so far. * @param base The LPI2C peripheral base address. * @param handle Pointer to the LPI2C master driver handle. * @param[out] count Number of bytes transferred so far by the non-blocking transaction. * @retval kStatus_Success * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. */
status_t LPI2C_MasterTransferGetCount(LPI2C_Type *base, lpi2c_master_handle_t *handle, size_t *count);
/*! * @brief Terminates a non-blocking LPI2C master transmission early. * * @note It is not safe to call this function from an IRQ handler that has a higher priority than the * LPI2C peripheral's IRQ priority. * * @param base The LPI2C peripheral base address. * @param handle Pointer to the LPI2C master driver handle. * @retval kStatus_Success A transaction was successfully aborted. * @retval #kStatus_LPI2C_Idle There is not a non-blocking transaction currently in progress. */
void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle);
/*@}*/
/*! @name IRQ handler */
/*@{*/
/*! * @brief Reusable routine to handle master interrupts. * @note This function does not need to be called unless you are reimplementing the * nonblocking API's interrupt handler routines to add special functionality. * @param base The LPI2C peripheral base address. * @param handle Pointer to the LPI2C master driver handle. */
void LPI2C_MasterTransferHandleIRQ(LPI2C_Type *base, lpi2c_master_handle_t *handle);
/*@}*/
Slave:
/*! @name Slave non-blocking */
/*@{*/
/*! * @brief Creates a new handle for the LPI2C slave non-blocking APIs. * * The creation of a handle is for use with the non-blocking APIs. Once a handle * is created, there is not a corresponding destroy handle. If the user wants to * terminate a transfer, the LPI2C_SlaveTransferAbort() API shall be called. * * @note The function also enables the NVIC IRQ for the input LPI2C. Need to notice * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to * enable the associated INTMUX IRQ in application. * @param base The LPI2C peripheral base address. * @param[out] handle Pointer to the LPI2C slave driver handle. * @param callback User provided pointer to the asynchronous callback function. * @param userData User provided pointer to the application callback data. */
void LPI2C_SlaveTransferCreateHandle(LPI2C_Type *base,
lpi2c_slave_handle_t *handle,
lpi2c_slave_transfer_callback_t callback,
void *userData);
/*! * @brief Starts accepting slave transfers. * * Call this API after calling I2C_SlaveInit() and LPI2C_SlaveTransferCreateHandle() to start processing * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the * callback that was passed into the call to LPI2C_SlaveTransferCreateHandle(). The callback is always invoked * from the interrupt context. * * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to * the OR'd combination of #lpi2c_slave_transfer_event_t enumerators for the events you wish to receive. * The #kLPI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and * receive events that are always enabled. In addition, the #kLPI2C_SlaveAllEvents constant is provided as * a convenient way to enable all events. * * @param base The LPI2C peripheral base address. * @param handle Pointer to lpi2c_slave_handle_t structure which stores the transfer state. * @param eventMask Bit mask formed by OR'ing together #lpi2c_slave_transfer_event_t enumerators to specify * which events to send to the callback. Other accepted values are 0 to get a default set of * only the transmit and receive events, and #kLPI2C_SlaveAllEvents to enable all events. * * @retval kStatus_Success Slave transfers were successfully started. * @retval #kStatus_LPI2C_Busy Slave transfers have already been started on this handle. */
status_t LPI2C_SlaveTransferNonBlocking(LPI2C_Type *base, lpi2c_slave_handle_t *handle, uint32_t eventMask);
/*! * @brief Gets the slave transfer status during a non-blocking transfer. * @param base The LPI2C peripheral base address. * @param handle Pointer to i2c_slave_handle_t structure. * @param[out] count Pointer to a value to hold the number of bytes transferred. May be NULL if the count is not * required. * @retval kStatus_Success * @retval kStatus_NoTransferInProgress */
status_t LPI2C_SlaveTransferGetCount(LPI2C_Type *base, lpi2c_slave_handle_t *handle, size_t *count);
/*! * @brief Aborts the slave non-blocking transfers. * @note This API could be called at any time to stop slave for handling the bus events. * @param base The LPI2C peripheral base address. * @param handle Pointer to lpi2c_slave_handle_t structure which stores the transfer state. * @retval kStatus_Success * @retval #kStatus_LPI2C_Idle */
void LPI2C_SlaveTransferAbort(LPI2C_Type *base, lpi2c_slave_handle_t *handle);
/*@}*/
/*! @name Slave IRQ handler */
/*@{*/
/*! * @brief Reusable routine to handle slave interrupts. * @note This function does not need to be called unless you are reimplementing the * non blocking API's interrupt handler routines to add special functionality. * @param base The LPI2C peripheral base address. * @param handle Pointer to lpi2c_slave_handle_t structure which stores the transfer state. */
void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle);
/*@}*/
边栏推荐
- A Kuan food: the battle for "the first share of convenience food" continues
- Musk's "good friend" impacts the largest IPO of Hong Kong stocks in 2022
- Discussion on outsourcing safety development management and control
- 清除交换机配置、配置镜像端口以及Wireshark抓包(以Huawei S5720为例)
- HMS core machine learning service ID card identification function to achieve efficient information entry
- What is the relationship between CSC securities and qiniu school? Is it safe to open a brokerage account
- PCB电路板设计都有哪些注意事项?
- Design and implementation of server security audit system
- 这3个后生,比马化腾、张一鸣还狠
- ThinkPHP security development specification
猜你喜欢

Rename all files in the folder with one click

矩形覆盖面积

重磅,MapStruct 1.5 发布,这次终于支持Map转为Bean了!

1108. IP 地址无效化

浅论OCA\UV-OCA LOCA\SLOCA 四种全贴合工艺

Jenkins 通过Build periodically配置定时任务

XML实体注入漏洞

1108. IP address invalidation

Formation harmonyos I

Illustrated with pictures and texts -- wechat applet to obtain the user's geographic location information and call Tencent map API to obtain the user's specific location
随机推荐
Introduction to Clair, a container static security vulnerability scanning tool
Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关
[yolov5s target detection] opencv loads onnx model for reasoning on GPU
MySQL 5.6.49 企业版设置密码复杂度策略
ThinkPHP security development specification
第k小__
Devsecops: ten things that should be done well
2022年高压电工判断题及答案
2-zabbix automatically add hosts using autodiscover
One's deceased father grind politics English average cent furnace! What is your current level?
Codeworks round 797 (Div. 3) F. shifting string problem solution
In the graduation season, tell me about my feelings when I first entered the workplace as a student
SSD【目标检测篇】
巨头局终战:即时零售
碎知识...
Is pension insurance a financial product? What is the expected return?
使用赞美提高绩效
异质化社群量化研究4丨RATE OF CHANGE WITH BANDS
中信建投券商是跟启牛学堂存在什么关系?开券商账户安全吗
SSD的anchor_box计算