通过原理图资料理解到OLED的控制芯片为SSD1309,该芯片与SPI1接口连接,根据程序源代码也可以看到使用的也是SPI总线。于是就像使用该芯片进行测试。因为CH2601的资料十分的匮乏,所有的参考都是通过参考例程。
与SPI有关的例程主要参考:W800芯片的例程,w800_at_port.c和SPI.C驱动例程。我于是参考该例程来修改OLED.C例程。为查看例程中只需要修改三个地方就可以了。
static void oled_gpio_init()
{
//
// csi_gpio_pin_init(&pin_clk, PA28);
// csi_gpio_pin_dir(&pin_clk, GPIO_DIRECTION_OUTPUT);
// csi_gpio_pin_init(&pin_mosi, PA29);
// csi_gpio_pin_dir(&pin_mosi, GPIO_DIRECTION_OUTPUT);
// csi_gpio_pin_init(&pin_cs, PA27);
// csi_gpio_pin_dir(&pin_cs, GPIO_DIRECTION_OUTPUT);
// csi_gpio_pin_init(&pin_miso, PA30); //dc
// csi_gpio_pin_dir(&pin_miso, GPIO_DIRECTION_OUTPUT);
int ret = 0;
ret = csi_spi_init(&spi_handle, 1);
if (ret < 0) {
printf("csi spi init failed\r\n");
return NULL;
}
csi_spi_mode(&spi_handle, SPI_MASTER);
ret = csi_spi_baud(&spi_handle, 500000);
LOGD(TAG, "#######################spi speed:%d\r\n", ret);
csi_spi_cp_format(&spi_handle, SPI_FORMAT_CPOL0_CPHA0);
csi_spi_frame_len(&spi_handle, SPI_FRAME_LEN_8);
csi_spi_select_slave(&spi_handle, 1);
#ifdef SPI_USE_DMA
csi_spi_attach_callback(&spi_handle, spi_event_cb, NULL);
csi_spi_link_dma(&spi_handle, NULL, &spi_recv_dma);
#endif
}
static void lcd_cs(uint8_t d)
{
if (d == 1) {
csi_gpio_pin_write(&pin_cs, GPIO_PIN_HIGH);
} else {
csi_gpio_pin_write(&pin_cs, GPIO_PIN_LOW);
}
}
//static void lcd_dc(uint8_t d)
//{
// if (d == 1) {
// csi_gpio_pin_write(&pin_miso, GPIO_PIN_HIGH);
// } else {
// csi_gpio_pin_write(&pin_miso, GPIO_PIN_LOW);
// }
//}
//
//static void lcd_sclk(uint8_t d)
//{
// if (d == 1) {
// csi_gpio_pin_write(&pin_clk, GPIO_PIN_HIGH);
// } else {
// csi_gpio_pin_write(&pin_clk, GPIO_PIN_LOW);
// }
//}
//
//static void lcd_sdin(uint8_t d)
//{
// if (d == 1) {
// csi_gpio_pin_write(&pin_mosi, GPIO_PIN_HIGH);
// } else {
// csi_gpio_pin_write(&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(&spi_handle, &Data, 1, AOS_WAIT_FOREVER);
if (ret < 0) {
LOGD("at spi", "send cmd err");
}
// lcd_dc(0);
// for (i = 0; i < 8; i++) {
// lcd_sclk(0);
// lcd_sdin((Data & 0x80) >> 7);
// Data = Data << 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(&spi_handle, &Data, 1, AOS_WAIT_FOREVER);
if (ret < 0) {
LOGD("at spi", "send cmd err");
}
// lcd_dc(1);
// for (i = 0; i < 8; i++) {
// lcd_sclk(0);
// lcd_sdin((Data & 0x80) >> 7);
// Data = Data << 1;
// lcd_sclk(1);
// }
// lcd_dc(1);
lcd_cs(1);
}
#endif
修改完成后写入ch2601芯片,但我觉得完成的时候,发现屏幕没有任何的反应。那我就想开启调式模式。但是诡异的事情出现了。
首先,是我使用CDK在程序main.c中加入断点。
但是无论这么样也无法中断。不论是直接开始还是开始下载都不能进入中断。
更诡异的是:无论在程序的任何地方都不能进入“断点”!而且不管使用什么样的编译也不行。
后来我把LOGD函数进入到main方法中就可以。但是在其它方法中就不行。
完整的代码片段如下:
/*
* Copyright (C) 2019-2020 Alibaba Group Holding Limited
*/
#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#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(&disp_buf1, buf1, buf2, 64 * 128);
/*Create a display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.buffer = &disp_buf1;
disp_drv.flush_cb = oled_flush;
disp_drv.rotated = 0;
lv_disp_drv_register(&disp_drv);
}
我的输出:
就是看不到输出。不知道为什么。知道目前有一个星期的时间了,也没有任何进展。
补充内容 (2021-9-1 10:17):
最后终于知道为什么了,硬件设计没有回避SPI MISO引脚
|