软件QSPI调试

相对于spi,qspi的是四条数据线并行传输数据,读写速度是普通spi的四倍。spi的工作模式有四种,但是qspi的工作模式只有两种也就是模式0(CPOL=0,CPOH=1)和模式3(CPOL=1,CPOL=1).
在使用软件qspi前,需要先使能对应芯片的qspi功能,一般是先读取使能位的状态寄存器,根据状态寄存器的qspi状态位判断该芯片当前是否已开启qspi,qspi与普通spi不能同时使用,在同一时刻只能有一种起作用。在qspi功能未开启前,需要先通过普通spi功能,来读写qspi使能状态位,开启qspi的功能。在通过普通spi读写状态寄存器时,需要先将hold和wp两个对应的io口拉高,来保证数据的有效传输。
在使用普通spi或者qspi读写的可以通过直接操作寄存器的方式来优化程序的执行速度。
在编写读写函数时要注意时序的问题,模式0:没有读写操作时,CLK引脚拉低,在时钟线的第一个边沿读写数据。
模式1:没有读写操作时,CLK引脚拉高,在时钟线的第二个边沿读写数据。

 __INLINE ret_code_t gpio_spi_drv_xfer(uint8_t *ptx_buf, uint16_t tx_length, uint8_t *prx_buf, uint16_t rx_length)
{

ret_code_t ret = NRF_SUCCESS;
uint8_t *rx_temp = prx_buf;

GPIO_CS_LOW;

if (tx_length)
{
	for(int i = 0; i < tx_length; i++)
	{
		uint8_t tx_temp = ptx_buf[i];
		for(int j = 0; j < 8; j++)
		{
			GPIO_CLK_LOW;

			if(tx_temp & 0x80)
			{
				GPIO_SPI_MOSI_HIGH;
			}
			else
			{
				GPIO_SPI_MOSI_LOW;
			}
			tx_temp <<= 1;
			GPIO_CLK_HIGH;
			
		}
	}
}

if (rx_length)
{		
	for(int i = 0; i < rx_length; i++)
	{
	#if (MISO_PIN != 0XFF)
		for(unsigned char j = 0; j < 8; j++)
		{
			GPIO_CLK_LOW;
			GPIO_CLK_HIGH;
			rx_temp[i] <<= 1;
			if(GPIO_SPI_MISO)
			{
				rx_temp[i]++;
			}
		}
	#endif
	}
}

GPIO_CS_HIGH;
return ret;
}

__INLINE ret_code_t gpio_qspi_drv_xfer(uint8_t *ptx_buf, uint16_t tx_length, uint8_t *prx_buf, uint16_t rx_length)
{
ret_code_t ret = NRF_SUCCESS;
uint8_t *rx_temp = prx_buf;
QSPI_LOCK();
GPIO_CS_LOW;

//qspi_drv_set_output();
if (tx_length > 0)
{
	QSPI_DRV_SET_OUTPUT(0xf0);// set pin (28-31) dir to output
	int size = tx_length;
	uint8_t byte_reg = 0;
	for(int i = 0; i < size; i++)
	{
	    uint8_t tx_temp = (ptx_buf[i] >> 4) & 0x0f;
		
		GPIO_CLK_LOW;
		//qspi_drv_write_data(tx_temp);
		byte_reg = QSPI_READ_WRITE_REG();// get the pin (24 - 31) state
		QSPI_DRV_WRITE_DAT(((tx_temp<<4)&0xf0) | (byte_reg&0x0f));
		__nop();
		GPIO_CLK_HIGH;
		__nop();
		
		GPIO_CLK_LOW;
		//qspi_drv_write_data(ptx_buf[i]);
		byte_reg = QSPI_READ_WRITE_REG();
		QSPI_DRV_WRITE_DAT(((ptx_buf[i]<<4)&0xf0) | (byte_reg&0x0f));
		__nop();
		GPIO_CLK_HIGH;
		__nop();
	}
	GPIO_CLK_HIGH;
}

__disable_irq();
if (rx_length)
{		
	//qspi_drv_set_intput();
	QSPI_DRV_SET_INPUT(0xf0);
	for(int i = 0; i < rx_length; i++)
	{	
		GPIO_CLK_LOW;
		__nop();__nop();__nop();
		GPIO_CLK_HIGH;
		rx_temp[i] = QSPI_DRV_READ_DAT();
		__nop();
		
		rx_temp[i] = rx_temp[i] & 0xf0;
		GPIO_CLK_LOW;
		__nop();__nop();__nop();
		GPIO_CLK_HIGH;
		rx_temp[i] |= (QSPI_DRV_READ_DAT() >> 4);
		__nop();
	}
	GPIO_CLK_HIGH;
}
__enable_irq();
GPIO_CS_HIGH;
QSPI_UNLOCK();
return ret;
}

你可能感兴趣的:(驱动)