非阻塞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通道示波器测试,当我尝试编写代码的循环时挂起代码spi_transfer_byte()checkin for spi_txh位。


/ **
****************************************************************************************
* @brief读取SPI外部接口API的功能。
*
* @param [in] * bufptr:指向存储器位置的指针,读取数据将被存储。
* @param [in]大小:要以字节读取的数据大小。
* @param [in] *回调:指向回调函数的指针。
****************************************************************************************
* /
void spi_hci_read_func(uint8_t * bufptr,uint32_t大小,void(*回调)(uint8_t))
{
// 完整性检查
assert_err(bufptr!= null);
assert_err(size!= 0);
assert_err(spi_env.rx.bufptr == null);
//准备RX参数
spi_env.rx.size = size;
spi_env.rx.bufptr = bufptr;
spi_env.rx.callback =回调;
//启用SPI中断
nvic_enableirq(spi_irqn);
}


/ **
****************************************************************************************
* @brief写入功能的SPI外部接口API。
*
* @param [in] * bufptr:指向要写入数据的存储器位置的指针。
* @param [in] size:要以字节字节写入的数据大小。
* @param [in] *回调:指向回调函数的指针。
****************************************************************************************
* /
void spi_hci_write_func(uint8_t * bufptr,uint32_t大小,void(*回调)(uint8_t))
{
// 完整性检查
assert_err(bufptr!= null);
assert_err(size!= 0);
assert_err(spi_env.tx.bufptr == null);
//准备TX参数
spi_env.tx.size = size;
spi_env.tx.bufptr = bufptr;
spi_env.tx.callback =回调;
//启用SPI中断
nvic_enableirq(spi_irqn);
//断言减排信号
spi_dready_high();
}


/ **
****************************************************************************************
* SPI中断处理程序的@brief导出功能。
****************************************************************************************
* /
void spi_handler(void)
{
// nvic_disableirq(spi_irqn);// << - 我应该禁用中断回调吗?
spi_transfer_data_isr();
}


/ **
****************************************************************************************
* @brief提供接收数据中断请求。它从SPI读取传入数据
*虽然spi_int_bit为1,并将它们保存到接收缓冲区指针。
*提供传输数据请求。它断言了指令信号来请求
*发送到主设备,当主设备提供时钟信号时数据
*执行交易。完成后,它将其取消置于变量信号。
*
****************************************************************************************
* /
静态void spi_transfer_data_isr(void)
{
void(* callback_transmit)(uint8_t)= null;
void(* callback_receive)(uint8_t)= null;
//读取可用的接收数据到SPI环境缓冲区指针
while(spi_data_rdy_getf())
{
//在FIFO中读取接收的字节并写字节。收到的任何更多字节都被忽略了。
spi_transfer_byte(spi_env.tx.bufptr,spi_env.rx.bufptr);
if(spi_env.rx.bufptr!= null)
{
//更新Rx参数
spi_env.rx.size--;
spi_env.rx.bufptr ++;
}
if(spi_env.tx.bufptr!= null)
{
//更新Rx参数
spi_env.tx.size--;
spi_env.tx.bufptr ++;
}
//检查是否已收到所有预期数据
if(spi_env.rx.size == 0 && spi_env.rx.bufptr!= null)
{
//检索回调指针
callback_receive = spi_env.rx.callback;
//清除回调指针
spi_env.rx.callback = null;
//重置Rx参数
spi_env.rx.bufptr = null;
休息;
}
//检查是否已传输所有数据
if(spi_env.tx.size == 0 && spi_env.tx.bufptr!= null)
{
spi_dready_low();// De-Assert Dready信号,发送完成
//检索回调指针
callback_transmit = spi_env.tx.callback;
//清除回调指针
spi_env.tx.callback = null;
//重置Tx参数
spi_env.tx.bufptr = null;
休息;
}
}
//禁用TX中断
spi_int_bit_clear();// < - 如果在传输函数中清除,则在传输所有字节之前可能退出时循环
nvic_disableirq(spi_irqn);
if(callback_receive!= null)
{
//呼叫处理程序
callback_receive(spi_status_ok);
}
否则if(callback_transmit!= null)
{
//呼叫处理程序
callback_transmit(spi_status_ok);
}
别的
{
assert_err(0);
}
}


/ **
****************************************************************************************
* @brief读取和/或写一个字节到spi。
*
* @param [in] wr_byte:要传输的字节。如果没有传输,则为null
* RD_BYTE:要收到的字节。如果没有任何东西必须读取。
****************************************************************************************
* /
__inline void spi_transfer_byte(const uint8_t * wr_byte,uint8_t * rd_byte)///////////////////////////////////////////////////////////// @@ vOuter:组合读取和写入一个功能,因此可以同时发生读写
{
if(wr_byte!= null)
{
而(getBits16(SPI_CTRL_REG,SPI_TXH)== 1);//等待SPI TX FIFO已满
setword16(spi_rx_tx_reg0,0xff&(0xAb));//发送字节
}
而(GetBits16(SPI_CTRL_REG1,SPI_BUSY)== 1);//等待SPI忙碌< - 系统挂在这里
if(rd_byte!= null)
{
* rd_byte = 0xff&getword16(spi_rx_tx_reg0);//从spi读取字节
}
别的
{
getword16(spi_rx_tx_reg0);//获得收到的字节并丢弃它。
}
// setword16(spi_clear_int_reg,0x01);//清除挂起标志< - 清除标志将在中断处理程序中退出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.
离线
最后一次露面:2个月2周前
职员
加入:2015-06-08 11:34
大家好,

大家好,

当时没有可用的图表,将SPI寄存器的状态映射到在SPI上的外部模式下执行的函数。我将向团队提供您的请求,以进一步对SPI进行外部配置的文件。

谢谢mt_dialog.