bigbat 发表于 2021-8-24 16:41

平头哥RVB2601板子-SPI测试

<p>通过原理图资料理解到OLED的控制芯片为SSD1309,该芯片与SPI1接口连接,根据程序源代码也可以看到使用的也是SPI总线。于是就像使用该芯片进行测试。因为CH2601的资料十分的匮乏,所有的参考都是通过参考例程。</p>

<p>与SPI有关的例程主要参考:W800芯片的例程,w800_at_port.c和SPI.C驱动例程。我于是参考该例程来修改OLED.C例程。为查看例程中只需要修改三个地方就可以了。</p>

<pre>
<code class="language-cpp">static void oled_gpio_init()
{
    //
//    csi_gpio_pin_init(&amp;pin_clk, PA28);
//    csi_gpio_pin_dir(&amp;pin_clk, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_mosi, PA29);
//    csi_gpio_pin_dir(&amp;pin_mosi, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_cs, PA27);
//    csi_gpio_pin_dir(&amp;pin_cs, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_miso, PA30); //dc
//    csi_gpio_pin_dir(&amp;pin_miso, GPIO_DIRECTION_OUTPUT);
    int      ret= 0;
   
        ret = csi_spi_init(&amp;spi_handle, 1);
    if (ret &lt; 0) {
      printf("csi spi init failed\r\n");
      return NULL;
    }

    csi_spi_mode(&amp;spi_handle, SPI_MASTER);
    ret = csi_spi_baud(&amp;spi_handle, 500000);

    LOGD(TAG, "#######################spi speed:%d\r\n", ret);
    csi_spi_cp_format(&amp;spi_handle, SPI_FORMAT_CPOL0_CPHA0);
    csi_spi_frame_len(&amp;spi_handle, SPI_FRAME_LEN_8);
    csi_spi_select_slave(&amp;spi_handle, 1);
#ifdef SPI_USE_DMA
    csi_spi_attach_callback(&amp;spi_handle, spi_event_cb, NULL);
    csi_spi_link_dma(&amp;spi_handle, NULL, &amp;spi_recv_dma);
#endif



}

static void lcd_cs(uint8_t d)
{
    if (d == 1) {
      csi_gpio_pin_write(&amp;pin_cs, GPIO_PIN_HIGH);
    } else {
      csi_gpio_pin_write(&amp;pin_cs, GPIO_PIN_LOW);
    }
}

//static void lcd_dc(uint8_t d)
//{
//    if (d == 1) {
//      csi_gpio_pin_write(&amp;pin_miso, GPIO_PIN_HIGH);
//    } else {
//      csi_gpio_pin_write(&amp;pin_miso, GPIO_PIN_LOW);
//    }
//}
//
//static void lcd_sclk(uint8_t d)
//{
//    if (d == 1) {
//      csi_gpio_pin_write(&amp;pin_clk, GPIO_PIN_HIGH);
//    } else {
//      csi_gpio_pin_write(&amp;pin_clk, GPIO_PIN_LOW);
//    }
//}
//
//static void lcd_sdin(uint8_t d)
//{
//    if (d == 1) {
//      csi_gpio_pin_write(&amp;pin_mosi, GPIO_PIN_HIGH);
//    } else {
//      csi_gpio_pin_write(&amp;pin_mosi, GPIO_PIN_LOW);
//    }
//}

void Write_Command(unsigned char Data)
{
    unsigned char i;
    int32_t ret = 0;
    lcd_cs(0);
       
        ret = csi_spi_send(&amp;spi_handle, &amp;Data, 1, AOS_WAIT_FOREVER);
    if (ret &lt; 0) {
      LOGD("at spi", "send cmd err");
    }
//    lcd_dc(0);
//    for (i = 0; i &lt; 8; i++) {
//      lcd_sclk(0);
//      lcd_sdin((Data &amp; 0x80) &gt;&gt; 7);
//      Data = Data &lt;&lt; 1;
//      lcd_sclk(1);
//    }
//    lcd_dc(1);
   
        lcd_cs(1);
}

void Write_Data(unsigned char Data)
{
    unsigned char i;
        int32_t ret = 0;

    lcd_cs(0);
       
        ret = csi_spi_send(&amp;spi_handle, &amp;Data, 1, AOS_WAIT_FOREVER);
    if (ret &lt; 0) {
      LOGD("at spi", "send cmd err");
    }
       
//    lcd_dc(1);
//    for (i = 0; i &lt; 8; i++) {
//      lcd_sclk(0);
//      lcd_sdin((Data &amp; 0x80) &gt;&gt; 7);
//      Data = Data &lt;&lt; 1;
//      lcd_sclk(1);
//    }
//    lcd_dc(1);

    lcd_cs(1);
}
#endif</code></pre>

<p>修改完成后写入ch2601芯片,但我觉得完成的时候,发现屏幕没有任何的反应。那我就想开启调式模式。但是诡异的事情出现了。</p>

<p>首先,是我使用CDK在程序main.c中加入断点。</p>

<p>&nbsp;但是无论这么样也无法中断。不论是直接开始还是开始下载都不能进入中断。</p>

<p>&nbsp;更诡异的是:无论在程序的任何地方都不能进入&ldquo;断点&rdquo;!而且不管使用什么样的编译也不行。</p>

<p>后来我把LOGD函数进入到main方法中就可以。但是在其它方法中就不行。</p>

<p>&nbsp;完整的代码片段如下:</p>

<pre>
<code class="language-cpp">/*
* Copyright (C) 2019-2020 Alibaba Group Holding Limited
*/


#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;aos/aos.h&gt;
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include "oled.h"

#define TAG "app"

int main(void)
{
    board_yoc_init();
       
    LOGD(TAG, "XXX %s\n", aos_get_app_version());
    oled_init();
        LOGD(TAG, "SPI end! YoC");
    while (1) {
      //LOGD(TAG, "Hello world! YoC");
      aos_msleep(1000);
    }

    return 0;
}



//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//Main Program
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// #define CONFIG_OLED_TEST
void oled_init()
{
        LOGD(TAG, "SPI start! YoC");
        oled_pinmux_init();
    oled_gpio_init();
    oled_initialize();

    // lv_disp porting
    /*Create a display buffer*/
    lv_disp_buf_init(&amp;disp_buf1, buf1, buf2, 64 * 128);

    /*Create a display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&amp;disp_drv); /*Basic initialization*/
    disp_drv.buffer   = &amp;disp_buf1;
    disp_drv.flush_cb = oled_flush;
    disp_drv.rotated= 0;
    lv_disp_drv_register(&amp;disp_drv);
}
</code></pre>

<p>我的输出:</p>

<p>&nbsp;就是看不到输出。不知道为什么。知道目前有一个星期的时间了,也没有任何进展。</p>

<p>&nbsp;</p>


补充内容 (2021-9-1 10:17):
最后终于知道为什么了,硬件设计没有回避SPIMISO引脚

littleshrimp 发表于 2021-8-24 22:20

<p>把oled_init函数放到main上边试试</p>

未来开发者 发表于 2021-8-25 17:03

<p>由于CH2601启用了XIP,代码直接运行在Flash上面,如果代码有修改,需要先烧录后才能运行断点。</p>

<p>具体步骤如下:</p>

<p>1、修改代码</p>

<p>2、编译</p>

<p>3、烧录</p>

<p>4、按系统复位键运行后,点击【Start Debugger】按键,调试器会连接设备并中断当前设备运行</p>

<p>5、在代码中增加断点,点击【Continue Debugger】按键,系统会继续运行,并停止在断点处。</p>

<p>注意,请确保断点位置还没执行到,否则将无法进入断点。如果断点在初始化阶段,可以在启动时加一个延时函数,确保在执行到断点之前就连接调试器。</p>

<p>例如,下面例程第20行增加5s延时,确保在执行到第21行断点之前,可以点击【Start Debugger】:</p>

<p>&nbsp;</p>

freebsder 发表于 2021-8-25 17:07

<p>辛苦辛苦,没资料的器件弄起来特别费劲</p>

bigbat 发表于 2021-8-26 08:50

未来开发者 发表于 2021-8-25 17:03
由于CH2601启用了XIP,代码直接运行在Flash上面,如果代码有修改,需要先烧录后才能运行断点。

具体步骤 ...

<p>按照你的提示已经试过了,除了能够得到点调式信息断点出不去!</p>

<p> &nbsp;</p>

littleshrimp 发表于 2021-8-27 19:27

<p>从你描述的现象来看像是没有成功编译你修改的文件,比如打印信息里有 app XXX,接着是app SPI end!YoC。而oled_init里的第一行&ldquo;LOGD(TAG, &quot;SPI start! YoC&quot;);&quot;似乎没有被执行,如果先不考虑断点和调试的问题,你可以试试修改能够成功输出的LOGD代码,看输出是否变化,比如在&rdquo;oled_init();&ldquo;函数上边的&rdquo;LOGD(TAG, &quot;XXX %s\n&quot;, aos_get_app_version());&ldquo;,试着把XXX改成其它字符看看会不会有变化 。</p>

<p>如果有变化,再看为什么没有进入oled_init();函数,因为函数里的第一句也是LOGD打印数据理论上没有道理什么都不显示,看你的代码main函数在上oled_init函数在下,main函数之前没见到oled_init的声明,这种情况理论应该编译不过,所以再试着把oled_init这个函数移到main上边看看。</p>

bigbat 发表于 2021-8-27 19:51

littleshrimp 发表于 2021-8-27 19:27
从你描述的现象来看像是没有成功编译你修改的文件,比如打印信息里有 app XXX,接着是app SPI end!YoC。而 ...

<p>我也觉得是没有被编译,但是我把函数名改了就不行了</p>

littleshrimp 发表于 2021-8-27 23:10

bigbat 发表于 2021-8-27 19:51
我也觉得是没有被编译,但是我把函数名改了就不行了

<p>试试改LOGD的输出看看结果有没有变化</p>

bigbat 发表于 2021-8-28 03:16

littleshrimp 发表于 2021-8-27 23:10
试试改LOGD的输出看看结果有没有变化

<p>我把#ifdef语句都去掉了,而且LOGD这个宏,就是放在oled.h中定义的,main.c中是引用该文件的</p>

littleshrimp 发表于 2021-8-28 06:50

bigbat 发表于 2021-8-28 03:16
我把#ifdef语句都去掉了,而且LOGD这个宏,就是放在oled.h中定义的,main.c中是引用该文件的

<p>修改打印输出,串口接收到的数据有变化吗?</p>

未来开发者 发表于 2021-8-29 20:46

本帖最后由 未来开发者 于 2021-8-29 20:48 编辑

<p>这种方法应该可以:<br />
<br />
1、右键工程,选择&ldquo;Options for xxx&rdquo;<br />
<br />
2、在配置页面中,点击【Debug】页签<br />
<br />
3、勾选【Load Application to Target】、【Auto Run】、【Stop at main】,如下图</p>

<p></p>

<p><br />
4、然后再次调试,就可以成功运行到断点处并且停下来了</p>

bigbat 发表于 2021-8-30 12:46

未来开发者 发表于 2021-8-29 20:46
这种方法应该可以:

1、右键工程,选择&ldquo;Options for xxx&rdquo;

2、在配置页面中,点击【Debug ...

<p></p>

<p>可以中断了,但是不知为什么程序跳过了LOGD指令。&nbsp;</p>

我爱下载 发表于 2021-8-30 16:01

bigbat 发表于 2021-8-26 08:50
按照你的提示已经试过了,除了能够得到点调式信息断点出不去!

&nbsp;

<p>在使用调试的时候,我发现我的调试状态和文件中的描述不相同,程序烧录有直接电机调试按钮是不能开始调试,需要复位系统,让她正常运行起来,然后在你希望跟踪的地方设置断点,在点击开始调试按钮,当然,这时候我的系统是没有啥反映的,不过,条件满足的时候却会进入断点。</p>

我爱下载 发表于 2021-8-30 16:05

<p>LCD显示的问题,我有个建议您参考一下,使用官方的驱动模式我觉得需要学习他的驱动编写方法,你可以考虑通过SPI接口的形式直接驱动这个LCD,如果可以的话,在进一步调试和系统的显示驱动挂钩,在使用lvgl图形库,感觉会好点。</p>

bigbat 发表于 2021-8-31 09:04

我爱下载 发表于 2021-8-30 16:05
LCD显示的问题,我有个建议您参考一下,使用官方的驱动模式我觉得需要学习他的驱动编写方法,你可以考虑通 ...

<p>谢谢,我改造驱动的目的就是SSD1309的资料比较少,而且就算有也比较麻烦。所以我就改一下它的数据发送我想就可以了。我这种方法在SSD1306下是成功的。</p>

bigbat 发表于 2021-9-1 10:22

<p>测试补充:在上面的测试中有几处需要补充,首先是引脚的初始化</p>

<pre>
<code class="language-cpp">static void oled_gpio_init()
{
    //
//    csi_gpio_pin_init(&amp;pin_clk, PA28);
//    csi_gpio_pin_dir(&amp;pin_clk, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_mosi, PA29);
//    csi_gpio_pin_dir(&amp;pin_mosi, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_cs, PA27);
//    csi_gpio_pin_dir(&amp;pin_cs, GPIO_DIRECTION_OUTPUT);
//    csi_gpio_pin_init(&amp;pin_miso, PA30); //dc
//    csi_gpio_pin_dir(&amp;pin_miso, GPIO_DIRECTION_OUTPUT);
    int      ret= 0;
   
        csi_pin_set_mux(PA28, PA28_SPI1_SCK);
    csi_pin_set_mux(PA29, PA29_SPI1_MOSI);
    csi_pin_set_mux(PA30, PA30_SPI1_MISO);
       
        ret = csi_spi_init(&amp;spi_handle1, 1);
    if (ret &lt; 0) {
      printf("csi spi init failed\r\n");
      return NULL;
    }

    csi_spi_mode(&amp;spi_handle1, SPI_MASTER);
    ret = csi_spi_baud(&amp;spi_handle1, 500000);

    LOGD(TAG, "#######################spi speed:%d\r\n", ret);
    csi_spi_cp_format(&amp;spi_handle1, SPI_FORMAT_CPOL0_CPHA0);
    csi_spi_frame_len(&amp;spi_handle1, SPI_FRAME_LEN_8);
    csi_spi_select_slave(&amp;spi_handle1, 1);
#ifdef SPI_USE_DMA
    csi_spi_attach_callback(&amp;spi_handle1, spi_event_cb, NULL);
    csi_spi_link_dma(&amp;spi_handle1, NULL, &amp;spi_recv_dma);
#endif



}
</code></pre>

<p>关键就是引脚功能的打开:csi_pin_set_mux(PA28, PA28_SPI1_SCK);</p>

<p>这里需要先把引脚打开,才可以。引脚的MISO与芯片的DC相连连接</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

未来开发者 发表于 2021-9-1 11:23

bigbat 发表于 2021-8-30 12:46
可以中断了,但是不知为什么程序跳过了LOGD指令。&nbsp;

<p>应该是SPI已被OLED屏使用,所以无法输出</p>

bigbat 发表于 2021-9-1 11:54

未来开发者 发表于 2021-9-1 11:23
应该是SPI已被OLED屏使用,所以无法输出

<p>问题也已解决,目前SPI可以使用了图像正常显示。谢谢你提供的调式功能,好多问题都已解决或已知道方向了。</p>

littleshrimp 发表于 2021-9-2 20:40

bigbat 发表于 2021-9-1 11:54
问题也已解决,目前SPI可以使用了图像正常显示。谢谢你提供的调式功能,好多问题都已解决或已知道方向了 ...

<p>问题都出在哪些地方?</p>

bigbat 发表于 2021-9-3 11:11

littleshrimp 发表于 2021-9-2 20:40
问题都出在哪些地方?

<p>主要问题:</p>

<p>1、SPI的引脚冲突,SSD1309的MISO和DC连接,因为是单相的所以就与MISO连接了。导致初始化时冲突。</p>

<p>2、开始时无法调试,很多问题无法探测</p>

<p>3、资料缺乏API函数主要是靠例程分析</p>
页: [1] 2
查看完整版本: 平头哥RVB2601板子-SPI测试