//初始化QSPI接口
//返回值:0,成功;
// 1,失败;
u8 QSPI_Init(void)
{
#if 1
// 这里用的是QSPI bank2
// CS: PC11
// CLK: PB2
// IO0: PE7
// IO1: PE8
// IO2: PE9
// IO3: PE10
u32 tempreg=0;
RCC->AHB4ENR|=1<<0; //使能GPIOA时钟
RCC->AHB4ENR|=1<<1; //使能GPIOB时钟
RCC->AHB4ENR|=1<<2; //使能GPIOC时钟
RCC->AHB4ENR|=1<<3; //使能GPIOD时钟
RCC->AHB4ENR|=1<<4; //使能GPIOE时钟
RCC->AHB3ENR|=1<<14; //QSPI时钟使能
// led PA3
GPIO_Set(GPIOA,1<<3,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);
GPIO_Pin_Set(GPIOA, 1 << 3, 1);
// RS485_TX PC7
GPIO_Set(GPIOC,1<<7,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);
GPIO_Pin_Set(GPIOC, 1 << 7, 1);
GPIO_Pin_Set(GPIOC, 1 << 7, 1);
// BANK2
//PB2 QUADSPI1_CLK
GPIO_Set(GPIOB,1<<2,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);
//PC11 QUADSPI1_BK2_NCS
GPIO_Set(GPIOC,1<<11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);
// 这里一定要PP, OD即使上拉驱动能力不够
//PE7, PE8, PE9, PE10 QUADSPI1_BK2_IO0, IO1, IO2, IO3
GPIO_Set(GPIOE,0x0F << 7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_NONE);
// Table 8. Port A alternate functions
GPIO_AF_Set(GPIOB,2,9); //PB2,AF9
GPIO_AF_Set(GPIOC,11,9); //PC11,AF9
GPIO_AF_Set(GPIOE,7,10); //PE7,AF10
GPIO_AF_Set(GPIOE,8,10); //PE8,AF10
GPIO_AF_Set(GPIOE,9,10); //PE9,AF10
GPIO_AF_Set(GPIOE,10,10); //PE10,AF10
RCC->AHB3RSTR|=1<<14; //复位QSPI
RCC->AHB3RSTR&=~(1<<14); //停止复位QSPI
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
{
//QSPI时钟默认来自rcc_hclk3(由RCC_D1CCIPR的QSPISEL[1:0]选择)
tempreg=(3-1)<<24; //设置QSPI时钟为AHB时钟的1/2,即200M/2=100Mhz,10ns // 240/3:80MHz
tempreg|=(4-1)<<8; //设置FIFO阈值为4个字节(最大为31,表示32个字节)
tempreg|=1<<7; // 0:选择FLASH1, 1:选择FLASH2
tempreg|=0<<6; //禁止双闪存模式
tempreg|=1<<4; //采样移位半个周期(DDR模式下,必须设置为0)
QUADSPI->CR=tempreg; //设置CR寄存器
tempreg=(19-1)<<16; //设置FLASH大小为2^25=32MB
tempreg|=(5-1)<<8; //片选高电平时间为5个时钟(10*5=50ns),即手册里面的tSHSL参数
tempreg|=1<<0; //Mode3,空闲时CLK为高电平
QUADSPI->DCR=tempreg; //设置DCR寄存器
QUADSPI->CR|=1<<0; //使能QSPI
}else
return 1;
return 0;
#else
u32 tempreg=0;
RCC->AHB4ENR|=1<<1; //使能PORTB时钟
RCC->AHB4ENR|=1<<5; //使能PORTF时钟
RCC->AHB3ENR|=1<<14; //QSPI时钟使能
GPIO_Set(GPIOB,1<<2,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PB2复用功能输出
GPIO_Set(GPIOB,1<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PB6复用功能输出
GPIO_Set(GPIOF,0XF<<6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU); //PF6~9复用功能输出
GPIO_AF_Set(GPIOB,2,9); //PB2,AF9
GPIO_AF_Set(GPIOB,6,10); //PB6,AF10
GPIO_AF_Set(GPIOF,6,9); //PF6,AF9
GPIO_AF_Set(GPIOF,7,9); //PF7,AF9
GPIO_AF_Set(GPIOF,8,10); //PF8,AF10
GPIO_AF_Set(GPIOF,9,10); //PF9,AF10
RCC->AHB3RSTR|=1<<14; //复位QSPI
RCC->AHB3RSTR&=~(1<<14); //停止复位QSPI
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
{
//QSPI时钟默认来自rcc_hclk3(由RCC_D1CCIPR的QSPISEL[1:0]选择)
tempreg=(2-1)<<24; //设置QSPI时钟为AHB时钟的1/2,即200M/2=100Mhz,10ns
tempreg|=(4-1)<<8; //设置FIFO阈值为4个字节(最大为31,表示32个字节)
tempreg|=1<<7; // 0:选择FLASH1, 1:选择FLASH2
tempreg|=0<<6; //禁止双闪存模式
tempreg|=1<<4; //采样移位半个周期(DDR模式下,必须设置为0)
QUADSPI->CR=tempreg; //设置CR寄存器
tempreg=(25-1)<<16; //设置FLASH大小为2^25=32MB
tempreg|=(5-1)<<8; //片选高电平时间为5个时钟(10*5=50ns),即手册里面的tSHSL参数
tempreg|=1<<0; //Mode3,空闲时CLK为高电平
QUADSPI->DCR=tempreg; //设置DCR寄存器
QUADSPI->CR|=1<<0; //使能QSPI
}else return 1;
return 0;
#endif
}
|