关于esp8266使用hspi做从机(slave)遇到的问题

ldcung
Posts: 5
Joined: Tue Jul 12, 2016 10:48 pm

关于esp8266使用hspi做从机(slave)遇到的问题

Postby ldcung » Tue Jul 12, 2016 11:47 pm

大家好,我在官方提供的ESP8266_NONOS_SDK V1.5.4中的AT工程基础上进行开发,我尝试使用esp8266的HSPI做为从机(Hspi slave)接收外部mcu发来的数据,但是在实现的过程中遇到一些问题。
我根据8J-ESP8266__SPI-WiFi_Passthrough_2-Interrupt_Mode__CN_v0.1.pdf文档中spi从机通信协议的说明,把外部mcu(spi 主机)设置成spi mode0,通信速率设置为500K,每次发送34个字节(命令0x02+地址0x00+32字节数据)。设置完成后,我通过逻辑分析仪捕获spi主机输出的波形,是我期望输出的波形。
然后,我在ESP8266程序里做了如下工作:
1.有用户程序初始化函数里初始化了spi从机。代码如下:
void ICACHE_FLASH_ATTR user_init(void)
{
led_gpio_init();
user_link_led_timer_init();
at_init();
at_port_print("\r\nready\r\n");
spi_slave_init(HSPI, 32);
}

spi_slave_init函数内容是采用官方默认的,并没有做修改。
2.在spi的从机中断函数void spi_slave_isr_handler(void *para)中添加了一些打印语句,代码如下:

void spi_slave_isr_handler(void *para)
{
uint32 regvalue,calvalue;
static uint8 state =0;
uint32 recv_data,send_data;
os_printf("spi_slave_isr\n");
if(READ_PERI_REG(0x3ff00020)&BIT4)
{
//following 3 lines is to clear isr signal
CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI), 0x3ff);
}
else if(READ_PERI_REG(0x3ff00020)&BIT7)
{ //bit7 is for hspi isr,
os_printf("hspi ISR\n");
regvalue=READ_PERI_REG(SPI_SLAVE(HSPI));
CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),//关闭中断使能
SPI_TRANS_DONE_EN|
SPI_SLV_WR_STA_DONE_EN|
SPI_SLV_RD_STA_DONE_EN|
SPI_SLV_WR_BUF_DONE_EN|
SPI_SLV_RD_BUF_DONE_EN);
SET_PERI_REG_MASK(SPI_SLAVE(HSPI), SPI_SYNC_RESET);
CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),//清中断标志
SPI_TRANS_DONE|
SPI_SLV_WR_STA_DONE|
SPI_SLV_RD_STA_DONE|
SPI_SLV_WR_BUF_DONE|
SPI_SLV_RD_BUF_DONE);
SET_PERI_REG_MASK(SPI_SLAVE(HSPI), //中断使能
SPI_TRANS_DONE_EN|
SPI_SLV_WR_STA_DONE_EN|
SPI_SLV_RD_STA_DONE_EN|
SPI_SLV_WR_BUF_DONE_EN|
SPI_SLV_RD_BUF_DONE_EN);
if(regvalue&SPI_TRANS_DONE)//传输完成?
{
os_printf("translate done\n");
}
if(regvalue&SPI_SLV_WR_BUF_DONE)//写从机buff完成?
{
os_printf("write buff done\n");
GPIO_OUTPUT_SET(0, 0);
//将寄存器接收数据搬入内存
idx=0;
while(idx<8)//取8次,每次取出一个32位数,共取出32*8=256位,也即32个字节
{
recv_data=READ_PERI_REG(SPI_W0(HSPI)+(idx<<2));
spi_data[idx<<2] = recv_data&0xff;
spi_data[(idx<<2)+1] = (recv_data>>8)&0xff;
spi_data[(idx<<2)+2] = (recv_data>>16)&0xff;
spi_data[(idx<<2)+3] = (recv_data>>24)&0xff;
idx++;
}
//add system_os_post here
GPIO_OUTPUT_SET(0, 1);//用于通知主机,数据已经读取完成
os_printf("receive finish\n");

}
if(regvalue&SPI_SLV_RD_BUF_DONE)
{
os_printf("read buff done\n");
//it is necessary to call GPIO_OUTPUT_SET(2, 1), when new data is preped in SPI_W8-15 and needs to be sended.
GPIO_OUTPUT_SET(2, 0);
//add system_os_post here
//system_os_post(USER_TASK_PRIO_1,WR_RD,regvalue);

}
}
else if(READ_PERI_REG(0x3ff00020)&BIT9)
{ //bit7 is for i2s isr,
os_printf("3\n");
}
}

在进行主机从机通信测试时,用主机一次发送34字节(命令0x02+地址0x00+32字节数据),结果发现os_printf("hspi ISR\n");被执行了十几次(约12次,每次打印出的字符串条数有差异),也即 else if(READ_PERI_REG(0x3ff00020)&BIT7)判断条件被触发约12次,而每次对应 if(regvalue&SPI_TRANS_DONE)条件也均会满足,os_printf("translate done\n");会执行并打印字符串。但是 if(regvalue&SPI_SLV_WR_BUF_DONE)条件总是不满足。当我尝试用主机发送读数据指令(0x03,0x00)时,得到的效果也如上所述,并不会触发if(regvalue&SPI_SLV_RD_BUF_DONE)。我尝试打印出regvalue的值,得到的结果为0x66f003f0,每次得到的结果不同,但是最后的三个数字总是3f0。


我现在的疑问是
1.主机一次发送34字节时,为什么会触发进入中断函数十几次,而不是一次,不是34次?
2.为什么SPI_SLV_WR_BUF_DONE和SPI_SLV_RD_BUF_DONE条件总是不被触发?是不是我哪里没有配置好,或者测试的方法有误?

另外,我尝试过用HSPI做为master主动往外发出数据,用逻辑分析仪观察波形,可以得到相应的波形,可以确定hspi的引脚是没有弄错的。

如果哪位朋友有做过,还请不吝指点,不胜感激!!!

ldcung
Posts: 5
Joined: Tue Jul 12, 2016 10:48 pm

Re: 关于esp8266使用hspi做从机(slave)遇到的问题

Postby ldcung » Wed Jul 13, 2016 3:02 pm

我发现了问题所在。由于对spi通信不熟悉,导致接线错误,才导致了上面的现象。spi主机和从机之间接线应该是这样的:
CS--------CS
MOSI--------MOSI
MISO--------MISO
CLK--------CLK
但是我把MOSI和MISO交叉接了,即主机MOSI接了从机的MISO,而主机的MISO接了从机的MOSI,这是不对的。
我更换回来之后,就通信正常了。esp8266可以正确接收到外部cpu发过来的32bytes数据。

coffeerr2004001
Posts: 2
Joined: Wed Aug 26, 2015 2:42 pm

Re: 关于esp8266使用hspi做从机(slave)遇到的问题

Postby coffeerr2004001 » Fri Aug 12, 2016 7:08 pm

:P

aozima
Posts: 1
Joined: Sun Aug 27, 2017 2:02 am

Re: 关于esp8266使用hspi做从机(slave)遇到的问题

Postby aozima » Sun Aug 27, 2017 2:05 am

ESP8266做SPI从机时,最高速率可以到多少M?

从机接收主要是用DMA方式还是FIFO方式?

Heirun
Posts: 1
Joined: Mon May 27, 2019 5:31 pm

Re: 关于esp8266使用hspi做从机(slave)遇到的问题

Postby Heirun » Mon May 27, 2019 5:49 pm

请问一下ESP8266的HSPI可以支持标准四线SPI吗?如果不行的话,那两个中断管脚可以设置成除GPIO0和GPIO2外其他的管脚吗?

Who is online

Users browsing this forum: No registered users and 7 guests