这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 开源硬件 » [转]STM32MP157A-DK1测评(4)UART与SPI设备访问

共1条 1/1 1 跳转至

[转]STM32MP157A-DK1测评(4)UART与SPI设备访问

助工
2020-04-20 10:42:44     打赏

板子上 ST-Link 的虚拟串口是连在 STM32MP157A 的 UART4 上的。如果在系统插卡状态,启动到 u-boot 阶段的时候在终端里键入字符使之进入交互模式,再使用 OpenOCD 对MPU进行调试,可以获得一个更好的软件环境。我发现这个状态下ROM、SYSRAM都没有被限制访问,外部的SDRAM也初始化过了可以用。

  想必 UART4 是已经初始化过了,u-boot需要用它。那么我直接访问 UART4 的寄存器来发送字符如何?从手册里查到 UART4 的基本地址是 0x40010000, 发送用数据寄存器 TDR 偏移量是 0x28. 那么先试试用 OpenOCD 的 mwb 命令往 0x40010028 地址写一个字节数据,看串口终端是否有内容。一试果然有字符收到。

  在这个环境下,用 UART4 来发送数据就和 MCU 的操作差不多了。现在不碰中断、DMA这些,就用查询状态寄存器的方式,写个发送字符的函数:

void uart_wchar(uint8_t ch)
{
    while(!(UART4->ISR & USART_ISR_TXE));
    UART4->TDR = ch;
}

以及输出一个字符串的函数:

void uart_wstr(const char *s)
{
    while(*s)
        uart_wchar(*s++);
}

  看起来就跟 STM32 MCU 一样的。这就对了。

 

  再试试 SPI.  从扩展的插针那里可以找到 SPI4 的相关引脚,可以连个 SPI 接口的 LCD 模块试一下。

  SPI5 的设备地址是 0x44009000. 但我试了一下向寄存器写值——无效。

  按照 STM32 MCU 的经验,这是 SPI5 的设备时钟没有使能,需要对 RCC 中的 APBxENR 进行操作。那么就搜索一下手册里 SPI5EN 关键字,立即找到一个:

有这个寄存器位,不过不在 APB2ENR 寄存器,而是 MP_APB2ENSETR (还有一个 MP_APB2ENCLRR用来清除),就把 STM32 MCU 那样用一个寄存器置写0/1换成了用两个寄存器分别置位/复位的操作方式。特别的,这个寄存器是给 MPU (Cortex-A7)用的,给MCU (Cortex-M4)的还有 MC_APB2ENSETR 寄存器。看来,STM32MP157 上面对硬件资源的分配是更复杂的,也许 A7 核启用了对 SPI5 的访问以后,M4 核就不能访问了,待后面我再测试是否是这样。

  于是我在程序中用了一行

    RCC->MP_APB2ENSETR = RCC_MC_APB2ENSETR_SPI5EN;
来启用 SPI5 设备,再对它的寄存器进行初始化。

  看 SPI5 和以往 MCU 的 SPI 是否兼容,可以通过看寄存器表来判断。

  这寄存器设置和我用过的 F0/F4/L4 的SPI寄存器差别明显,看来是升级了。不过,从手册里居然看到了 H7 的字样(难道是从 STM32H7 开始升级的)。

和我用过的老的 SPI 比起码 FIFO 是升级了。那就学着用用,写段程序。

void config_spi5(void)
{
    SPI5->CR1=0;    // disable (if already configured)
    SPI5->IFCR = 0xFFFF; // clear all flags
    SPI5->CFG1=SPI_CFG1_MBR_2|SPI_CFG1_MBR_1 // master clock/128
        |0<<SPI_CFG1_FTHLV_Pos    // FIFO level: 1-data
        |7<<SPI_CFG1_DSIZE_Pos;    // data size: 8-bit
    SPI5->CFG2=SPI_CFG2_SSOE|SPI_CFG2_MASTER;
    SPI5->CR2=0;    // TSIZE and reload
    SPI5->CR1=SPI_CR1_SPE;
}

  依然可以用 MCU 的思维来写代码,就是些寄存器嘛,可能跟 STM32H7 的写法一致。最后我实现的发送指定长度数据的函数是这样的(因为给LCD用,不考虑接收了)

void spi_write(const uint8_t *buf, uint16_t sz)
{
    int i;
    if(!sz)
        return;
    if(SPI5->CR1 & SPI_CR1_CSTART)
        return;
    SPI5->CR2=sz;
    SPI5->CR1 |= SPI_CR1_CSTART;
    for(i=0;i<sz;i++)
    {
        while(!(SPI5->SR & SPI_SR_TXP));
        *(volatile uint8_t *)&SPI5->TXDR = buf;
    }
    while(!(SPI5->SR & SPI_SR_EOT))
    {}
    while((GPIOF->IDR & 1<<6)==0)    // NSS Low
    {}
    SPI5->IFCR = SPI_IFCR_EOTC;
}

  STM32MP157A 的 SPI master 可以自己管理 NSS 脚,不像老的 SPI 那样不传输的时候 master NSS 输出一直是低。

 

  最后上图,测试LCD显示的效果(从UART接收字符,按点阵字库的数据在 96x64 LCD 上画出来符号。程序也就沿用我为 MCU 写的程序,移植到这里)。

  因为没有用中断、DMA操作,到目前程序写法和 Cortex-m MCU 完全一致。为了方便编译,写一个 Makefile

1.png

以及 Linker Script, 用来确定地址

2.png

3.png

4.png




关键词: STM32MP157A-DK1     寄存器    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]