W806外扩PSRAM程序

发布于 2022-06-30 11:57:26

一 硬件准备
1、Air103核心板,完美兼容W806,预留PSRAM焊盘,9.9元包邮
2、LY68L6400,64M bit PSARM芯片
二 CDK
1、使能PSRAM时钟
__HAL_RCC_PSRAM_CLK_ENABLE();
(#define __HAL_RCC_PSRAM_CLK_ENABLE() SET_BIT(RCC->CLK_EN, RCC_CLK_EN_QSRAM))
2、复用PSRAM io,采用QSPI模式

__HAL_AFIO_REMAP_PSRAM_CS(GPIOB, GPIO_PIN_27);
__HAL_AFIO_REMAP_PSRAM_CLK(GPIOA, GPIO_PIN_15);
__HAL_AFIO_REMAP_PSRAM_MISO(GPIOB, GPIO_PIN_3);
__HAL_AFIO_REMAP_PSRAM_MOSI(GPIOB, GPIO_PIN_2);
__HAL_AFIO_REMAP_PSRAM_D2(GPIOB, GPIO_PIN_4);
__HAL_AFIO_REMAP_PSRAM_D3(GPIOB, GPIO_PIN_5);

(#define __HAL_AFIO_REMAP_PSRAM_CS(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOB) && (__IOPOSITION__ == GPIO_PIN_27))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT1(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)    

define __HAL_AFIO_REMAP_PSRAM_CLK(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOA) && (__IOPOSITION__ == GPIO_PIN_15))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT1(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)

define __HAL_AFIO_REMAP_PSRAM_MISO(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOB) && (__IOPOSITION__ == GPIO_PIN_3))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT4(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)        

define __HAL_AFIO_REMAP_PSRAM_MOSI(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOB) && (__IOPOSITION__ == GPIO_PIN_2))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT4(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)    

define __HAL_AFIO_REMAP_PSRAM_D2(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOB) && (__IOPOSITION__ == GPIO_PIN_4))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT4(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)    

define __HAL_AFIO_REMAP_PSRAM_D3(__HANDLE__, __IOPOSITION__) do{ \

                                            if ((__HANDLE__ == GPIOB) && (__IOPOSITION__ == GPIO_PIN_5))    \
                                            {                                                    \
                                                __AFIO_REMAP_SET_OPT4(__HANDLE__, __IOPOSITION__);    \
                                            }                                                    \
                                        }while (0)    )

3、PSRAM初始化,可以参照W800 初始化程序,下面是我修改的,也可以直接用
typedef volatile unsigned int TLS_REG;
static __inline void tls_reg_write32(unsigned int reg, unsigned int val)
{

*(TLS_REG *)reg = val;

}
static __inline unsigned int tls_reg_read32(unsigned int reg)
{

unsigned int val = *(TLS_REG *)reg;
return val;

}
void psram_init(void)
{

    value = tls_reg_read32(HR_PSRAM_CTRL_ADDR);
printf("HR_PSRAM_CTRL_ADDR-1 %d\r\n       ", value);
    value |= 0x03;
tls_reg_write32(HR_PSRAM_CTRL_ADDR, value);
do{
   value = tls_reg_read32(HR_PSRAM_CTRL_ADDR);
}while(value&0x01);    
value = 0xfffff000;
tls_reg_write32(HR_PSRAM_CTRL_ADDR, value);    
value =(tls_reg_read32(HR_PSRAM_CTRL_ADDR)&0xffffff0f) | 0x40; 
tls_reg_write32(HR_PSRAM_CTRL_ADDR, value);    
value =(tls_reg_read32(HR_PSRAM_CTRL_ADDR)&0xfffff8ff) | 0x600; 
tls_reg_write32(HR_PSRAM_CTRL_ADDR, value);    
value =(tls_reg_read32(HR_PSRAM_CTRL_ADDR)&0xffffffff) | 0x040 | 0x002; 
tls_reg_write32(HR_PSRAM_CTRL_ADDR, value);    
value =(tls_reg_read32(HR_PSRAM_OVERTIMER_ADDR)&0xfffff000) | 0x800; 
tls_reg_write32(HR_PSRAM_OVERTIMER_ADDR, value);

}
4、函数中验证
定义 unsigned int *membase = (unsigned int )(0x30000000);

for(num=0;num<1024;num++)  //每个数据4字节,每1024*2*4 个内存写一个数,1024次为8Mbyte,再读出来printf至电脑。
{
    membase[1024*2*num]=1024*2*num;
    HAL_Delay(10);
    printf("%d w-r  %d     %d   ", num,1024*2*num,membase[1024*2*num]);
    printf("\r\n");
}
HAL_Delay(1000);
for(num=0;num<1024;num++)
{
    HAL_Delay(10);
    printf("%d r-r  %d     %d   ", num,1024*2*num,membase[1024*2*num]);
    printf("\r\n");
}
HAL_Delay(1000);
0 条评论

发布
问题