亲爱的读者,
I am trying to implement SPI communication between the DA14580 and a host mcu, for data package transfer. The DA14580 is acting as a SPI slave (8-bit, POL=0, PHA=0, bi-directional FIFO, DREADY interrupt line, own flow control). As a starting point I used thespi_hci.c.。但是,我注意到了spi_hci_write_func()is blocking and is not - as thespi_hci_read_func()是 - 基于中断。我正在尝试制作写入功能中断,但有些事情对我来说不清楚:
- 从数据表中不清楚哪些位(例如spi_int_bit,spi_txh,spi_busy)设置/清除,何时。有可用的时序图吗?
- 是否可以使用此模块同时读写?(根据它应该的SPI规格)
目前,我正在使用总线海盗和2通道示波器测试,当我尝试编写代码的循环时挂起代码spi_transfer_byte()checkin for the SPI_TXH bit.
/ **
****************************************************************************************
* @brief读取SPI外部接口API的功能。
*
*@param[in] *bufptr: Pointer to the memory location the read data will be stored.
* @param [in]大小:要以字节读取的数据大小。
* @param [in] *回调:指向回调函数的指针。
****************************************************************************************
* /
void spi_hci_read_func(uint8_t * bufptr,uint32_t大小,void(*回调)(uint8_t))
{
// Sanity check
assert_err(bufptr!= null);
assert_err(size!= 0);
ASSERT_ERR(spi_env.rx.bufptr == NULL);
// Prepare RX parameters
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))
{
// Sanity check
assert_err(bufptr!= null);
assert_err(size!= 0);
ASSERT_ERR(spi_env.tx.bufptr == NULL);
// Prepare TX parameters
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,并将它们保存到接收缓冲区指针。
*提供传输数据请求。它断言了指令信号来请求
*transmit to the master and when the master provides a clock signal the data
*执行交易。完成后,它将其取消置于变量信号。
*
****************************************************************************************
* /
静态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 ++;
}
// Check if all expected data have been received
if (spi_env.rx.size == 0 && spi_env.rx.bufptr!=NULL)
{
//检索回调指针
callback_receive = spi_env.rx.callback;
// Clear callback pointer
spi_env.rx.callback = NULL;
//重置Rx参数
spi_env.rx.bufptr = NULL;
休息;
}
// Check if all data have been transmitted
if(spi_env.tx.size == 0 && spi_env.tx.bufptr!= null)
{
spi_dready_low();// De-Assert Dready信号,发送完成
//检索回调指针
callback_transmit = spi_env.tx.callback;
// Clear callback pointer
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: Byte to be transmitted. NULL if nothing is transmitted
* RD_BYTE:要收到的字节。如果没有任何东西必须读取。
****************************************************************************************
* /
__inline void spi_transfer_byte(const uint8_t * wr_byte,uint8_t * rd_byte)///////////////////////////////////////////////////////////// @@ vOuter:组合读取和写入一个功能,因此可以同时发生读写
{
if(wr_byte!= null)
{
while (GetBits16(SPI_CTRL_REG,SPI_TXH)==1); // Wait if SPI Tx FIFO is full
SetWord16(SPI_RX_TX_REG0, 0xFF&(0xab)); // Send byte
}
而(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); // Get received byte and discard it.
}
// setword16(spi_clear_int_reg,0x01);//清除挂起标志< - 清除标志将在中断处理程序中退出while循环。
}
似乎写信给了SP_RX_TX_REG0 does not effect the value of the register at all. Can something block access to this register?
这是一个信号线问题。
然而,SPI时间图非常有用。
我是关于信号SPI_Int_bit,SPI_TXH,SPI_BUSY的时序图的有用性。我正在研究类似的东西,并从更好地了解SPI时序来利润。
Regards,
Mabraun.
大家好,
当时没有图,地图s the states of the spi registers to the functions performed while being in external mode over spi. I will carry your request to the team for further documentation of the external configuration over spi.
谢谢mt_dialog.