SPI OLED设备调试记录

来源:互联网 发布:软件项目经理培训班 编辑:程序博客网 时间:2024/06/05 19:10

平台:MT6737M

OLED IC:ssd1331  有几种连接方式,我们用的是SPI。

---------------------------------------------------------------------------

知识储备:

SPI总线工作方式有四种,由时钟信号的极性及相位组合而成,

CPOL: 时钟极性选择,为0时SPI总线空闲为低电平,为1时SPI总线空闲为高电平。

CPHA:时钟相位选择,为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样。

MTK平台SPI的数据传输模式有:

1. FIFO,支持一次传输32bytes。

2. DMA,一次最多支持1024B,支持多次传输(length=loop*1024,1≤loop≤256)。

3. SPI控制器只有一个片选信号,故只支持一个从设备。


------------------------------------------------------------------------------

调试过程及遇到的问题:

1、第一步不免俗,注册一个SPI设备,SPI驱动。各平台路径会有差异,这个平台路径是:\kernel-3.18\drivers\spi\mediatek\mt6735

2、设备驱动加载成功,初始化按照datasheet power on时序,初始化代码发送,观看屏幕是否点亮了。

这里就涉及到两个很重要的东西,GPIO的设置和SPI参数的设置。GPIO设置略过,SPI参数一般都默认即可。另上面说的一个SPI只支持一个设备,不是绝对的,换个思想,GPIO模拟SPI。。。CS无非就是选中某个设备而已,对于这个设备来讲就一个高低电平。

3、屏幕点亮很顺利,因为在单片机上面已经调好了。时代久远,暂且不表。

4、按照默认配置FIFO,SPI总线速率不高,具体数值忘了。

我们项目是一个SPI接口接两个SPI设备,轮流切换,要做到同时刷新的效果,对速度上就要求比较高了。这里对SPI配置就小小的纠结了一番,折腾数小时,最终改1个地方搞定。(DMA,一次最多支持1024B,支持多次传输(length=loop*1024,1≤loop≤256)。)

spi_par->com_mod = DMA_TRANSFER;

static int spi_test_write_byte(struct spi_device *spi, char data)
{
 char buf[1];
 struct spi_message msg;
 struct spi_transfer xfer = {
  .len  = 1,
  .tx_buf  = buf,
  .cs_change = 0,
  .delay_usecs = 0,
  .speed_hz = (u32)40*1000*1000,
  .tx_dma = 0,
  .rx_dma = 0,
  .bits_per_word = 0,
 };
 buf[0] = data;
 spi_message_init(&msg);
 spi_message_add_tail(&xfer, &msg);
 return spi_sync(spi, &msg);
}

static int spi_test_write_bytes(struct spi_device *spi, const unsigned char *data, int len)
{
 struct spi_message msg;
 struct spi_transfer xfer = {
  .len  = len,
  .tx_buf  = data,
  .cs_change = 0,
  .delay_usecs = 0,
  .speed_hz = (u32)40*1000*1000,
  .tx_dma = 0,
  .rx_dma = 0,
  .bits_per_word = 0,
 };
 spi_message_init(&msg);
 spi_message_add_tail(&xfer, &msg);
 return spi_sync(spi, &msg);
}

DMA方式就可以直接用下面的函数,FIFO就老实用上面的吧。

5、最后解了一个bug,跟SPI无关,软件设计的缺陷,还是记录一下吧。

SPI一次性发送多个数据以防被其他打断一定要加锁,互斥锁,or 全局变量,互斥锁的原始做法。


好记性不如烂笔头。。。

0 0
原创粉丝点击