非阻塞SPI从实现

5个职位/ 0个新
最后发表
BB
离线
最后看到:3年10个月前
加入:2015-11-03 12:16
非阻塞SPI从实现

亲爱的读者,
我正在尝试实现DA14580和主机mcu之间的SPI通信,用于数据包传输。DA14580是作为一个SPI奴隶(8位,POL=0, PHA=0,双向FIFO,可怕的中断线,自己的流控制)。作为一个起点,我使用spi_hci.c.然而,我注意到spi_hci_write_func ()是阻塞而不是-作为spi_hci_read_func ()基于中断。我试图使写函数基于中断,然而一些事情是不清楚的我:
-从数据表中不清楚哪些位(例如SPI_INT_BIT, SPI_TXH, SPI_BUSY)何时被设置/清除。有没有时间安排图?
-是否可以同时读取和写入这个模块?(根据SPI规范,它应该是)

目前,我正在测试一个公共汽车盗版和一个2通道示波器,当我试图写代码挂在一个while循环spi_transfer_byte ()签入SPI_TXH位。


/**
****************************************************************************************
* @brief SPI外部接口API的读取功能。

@param[in] *bufptr:指向读取数据将被存储的内存位置的指针。
* @param[in] size:要读取的数据的大小,以字节为单位。
@param[in] *callback:指向回调函数的指针。
****************************************************************************************
*/
sp_hci_read_func (uint8_t *bufptr, uint32_t size, uint8_t)

/ /检查
ASSERT_ERR (bufptr ! = NULL);
ASSERT_ERR(大小! = 0);
ASSERT_ERR (spi_env.rx。bufptr = = NULL);
//准备RX参数
spi_env.rx。大小=大小;
spi_env.rx。bufptr = bufptr;
spi_env.rx。回调=回调;
//启用SPI中断
NVIC_EnableIRQ (SPI_IRQn);


/**
****************************************************************************************
* @brief SPI外部接口API的写函数。

*bufptr:指向要写入数据的内存位置的指针。
* @param[in] size:以字节为单位写入的数据的大小。
@param[in] *callback:指向回调函数的指针。
****************************************************************************************
*/
sp_hci_write_func (uint8_t *bufptr, uint32_t size, uint8_t)

/ /检查
ASSERT_ERR (bufptr ! = NULL);
ASSERT_ERR(大小! = 0);
ASSERT_ERR (spi_env.tx。bufptr = = NULL);
//准备TX参数
spi_env.tx。大小=大小;
spi_env.tx。bufptr = bufptr;
spi_env.tx。回调=回调;
//启用SPI中断
NVIC_EnableIRQ (SPI_IRQn);
/ /维护所信号
spi_dready_high ();


/**
****************************************************************************************
* @brief为SPI中断处理程序导出函数。
****************************************************************************************
*/
空白SPI_Handler(空白)

/ / NVIC_DisableIRQ (SPI_IRQn);// <<——我应该禁用中断回调吗?
spi_transfer_data_isr ();


/**
****************************************************************************************
* @brief为接收数据中断请求服务。它从SPI读取传入数据
*而SPI_INT_BIT为1,并将它们保存到接收缓冲区指针。
*为传输数据请求服务。它断言可怕信号请求
*发送给主机,当主机提供一个时钟信号的数据
事务被执行。在完成后,它取消了可怕的信号。

****************************************************************************************
*/
静态孔隙spi_transfer_data_isr(空白)

void (*callback_transmit) (uint8_t) = NULL;
void (*callback_receive) (uint8_t) = NULL;
//读取可用的接收数据到SPI环境缓冲区指针
而(spi_data_rdy_getf ())

//读取FIFO中接收到的字节并写入字节。接收到的任何字节都将被忽略。
spi_transfer_byte (spi_env.tx.bufptr spi_env.rx.bufptr);
如果(spi_env.rx.bufptr ! = NULL)

//更新RX参数
spi_env.rx.size——;
spi_env.rx.bufptr + +;

如果(spi_env.tx.bufptr ! = NULL)

//更新RX参数
spi_env.tx.size——;
spi_env.tx.bufptr + +;

//检查是否收到所有预期的数据
如果(spi_env.rx。&& spi_env.rx.bufptr!=NULL)

//获取回调指针
callback_receive = spi_env.rx.callback;
//清除回调指针
spi_env.rx。回调=零;
//重置RX参数
spi_env.rx。bufptr =零;
打破;

//检查是否所有数据已经传输
如果(spi_env.tx。&& spi_env.tx.bufptr!=NULL)

spi_dready_low ();//解除恐惧信号,发送完成
//获取回调指针
callback_transmit = spi_env.tx.callback;
//清除回调指针
spi_env.tx。回调=零;
//重置TX参数
spi_env.tx。bufptr =零;
打破;


//关闭TX中断
spi_int_bit_clear ();// <——如果在transfer函数中清除此值,则while循环可能在所有字节被传输之前退出
NVIC_DisableIRQ (SPI_IRQn);
如果(callback_receive ! = NULL)

/ /调用处理程序
callback_receive (SPI_STATUS_OK);

else if(callback_transmit != NULL)

/ /调用处理程序
callback_transmit (SPI_STATUS_OK);

其他的

ASSERT_ERR (0);



/**
****************************************************************************************
* @brief读取和/或写入一个字节到SPI。

@param[in] wr_byte:传输的字节。如果没有传输,则为NULL
* rd_byte:接收字节。如果不需要读取任何内容,则为NULL。
****************************************************************************************
*/
__INLINE void spi_transfer_byte(const uint8_t* wr_byte, uint8_t* rd_byte) //@@ wouter:将读和写合并到一个函数中,因此读和写可以同时发生

如果(wr_byte ! = NULL)

而(GetBits16 (SPI_CTRL_REG SPI_TXH) = = 1);//如果SPI Tx FIFO已满,则等待
SetWord16 (SPI_RX_TX_REG0, 0 xff (0 xab));/ /发送字节

而(GetBits16 (SPI_CTRL_REG1 SPI_BUSY) = = 1);// SPI忙时等待<——系统挂起这里
如果(rd_byte ! = NULL)

* rd_byte = 0 xff&getword16 (SPI_RX_TX_REG0);//从SPI读取字节

其他的

GetWord16 (SPI_RX_TX_REG0);//接收字节并丢弃它。

/ / SetWord16 (SPI_CLEAR_INT_REG 0 x01);//清除挂起标志<——清除标志将退出中断处理程序中的while循环。

关键词:
设备:
BB
离线
最后看到:3年10个月前
加入:2015-11-03 12:16
好像是给

似乎写入SP_RX_TX_REG0根本不会影响寄存器的值。是否有什么东西阻止访问这个寄存器?

BB
离线
最后看到:3年10个月前
加入:2015-11-03 12:16
是信号线的问题。

是信号线的问题。
尽管如此,SPI时间图还是非常有用的。

mabraun
离线
最后看到:3年6个月前
加入:2015-11-16 15:57
我赞同

我附送关于信号SPI_INT_BIT、SPI_TXH、SPI_BUSY的时序图。我正在做类似的事情,将受益于更好地理解SPI计时。

问候,
mabraun

MT_dialog
离线
最后看到:两个月两个星期前
工作人员
加入:2015-06-08 34
你好,

你好,

当时没有一个图表可以将spi寄存器的状态映射到在spi上处于外部模式时执行的函数。我将把您的请求传递给团队,以进一步记录spi上的外部配置。

由于MT_dialog