spi-lcd-st7789-驱动开发-imx6ul spi dma传输(6)

imx6ul spi dma传输分析

imx6ul sdk 里面spi 驱动做的比较完善,会自己判断是否满足dma传输的条件,如果满足dma传输就直接使用dma进行传输了。

那么imx 6ul平台spi使用dma传输的条件是什么呢?其实只要传输的bpw为1,2,4 然后数据长度为32的整数倍就可以使用dma传输了

imx 进行spi传输相关的代码如下:


static int spi_imx_transfer(struct spi_device *spi,
				struct spi_transfer *transfer)
{
	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
	//Mark by Jason 717628525@qq.com
	
	if (spi_imx->usedma)
		return spi_imx_dma_transfer(spi_imx, transfer);
	else
		return spi_imx_pio_transfer(spi, transfer);
		 
}

通过下面函数判断是否满足进行dma传输的条件:
static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
			 struct spi_transfer *transfer)
{
	struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
	unsigned int bpw;
	
	if (!master->dma_rx) {
		return false;
		
	}
		
	if (!transfer) {
		return false;
	}
		
	bpw = transfer->bits_per_word;
	if (!bpw)
		bpw = spi->bits_per_word;

	bpw = spi_imx_bytes_per_word(bpw);
	

	if (bpw != 1 && bpw != 2 && bpw != 4) {
		return false;
	}

	if (transfer->len < spi_imx->wml * bpw) {
		return false;
	}
	
	if (transfer->len % (spi_imx->wml * bpw)) {
		return false;
	}
	
	return true;
}


为了测试dma与传统spi传输的差异,驱动里面数据发送函数做了些处理:

/**
 * @brief	LCD底层SPI发送数据函数
 *
 * @param   data	数据的起始地址
 * @param   size	发送数据大小
 *
 * @return  void
 */
static void LCD_SPI_Send(u8 *data, u32 size)
{
	if (!use_dma_flag) {
		u32 i;
   		u32 delta;
	    
	    delta = size/0xFFFF;
	    
	    for(i = 0; i<=delta; i++)
	    {
	        if( i==delta )  /* 发送最后一帧数据 */ {
	            //SPI2_WriteData(&data[i*0xFFFF], size%0xFFFF); /SPI2_WriteData/替换linux接口
	            spi_lcd_st7789_send_data(&data[i*0xFFFF], size%0xFFFF);
	        } else {/* 超长数据一次发送0xFFFF字节数据 */
	            //SPI2_WriteData(&data[i*0xFFFF], 0xFFFF);       //SPI2_WriteData替换linux接口
	            spi_lcd_st7789_send_data(&data[i*0xFFFF], 0xFFFF);  
	        } 
	            
	    }
	} else {
		//printk(KERN_WARNING "%s:%d[dma t1]\n", __FUNCTION__, __LINE__);
		if (-1 == dma_split_size)  {
			spi_lcd_st7789_send_data(data, size); 
		} else {

			if (dma_split_size % 32 != 0) {
				printk(KERN_WARNING "dma_split_size shuold be 32x, use in normal mode\n");
			}
			u32 i;
	   		u32 delta;
		    
		    delta = size/dma_split_size;
		    
		    for(i = 0; i<=delta; i++)
		    {
		        if( i==delta )  /* 发送最后一帧数据 */ {
		            spi_lcd_st7789_send_data(&data[i*dma_split_size], size%dma_split_size);
		        } else {/* 超长数据一次发送0xFFFF字节数据 */
		            spi_lcd_st7789_send_data(&data[i*dma_split_size], dma_split_size);  
		        } 
		            
		    }
		}
		  
	}
	
}

传统模式直接对数据行进65535字节分片处理,如果是dma传输方式,插入模块时候设置了dma_split_size,就用dma_split_size作为分片传输大小。

否则dma传输分片大小直接设置为发送数据大小。

测试dma 模式与普通模式性能:

1. dma模式

insmod lcd_st7789.ko use_dma_flag=1

./test_spi_lcd_st7789 /dev/fb2

dma 模式:

Test drawing GREEN......

data 0xffffe007

[   68.656193] --->spi_imx_transfer:1154 len:115200 [spi_dma t00] #一帧开始

[   68.756468] --->spi_imx_transfer:1157 len:115200 [spi_dma t01] #一帧结束

Test drawing BLUE......

data 0x00001f00

[   69.674976] --->spi_imx_transfer:1154 len:115200 [spi_dma t00]

[   69.775234] --->spi_imx_transfer:1157 len:115200 [spi_dma t01]

Test drawing WHITE......

data 0xffffffff

[   70.694087] --->spi_imx_transfer:1154 len:115200 [spi_dma t00]

[   70.794338] --->spi_imx_transfer:1157 len:115200 [spi_dma t01]

Test drawing Black......

data 0x00000000

[   71.713737] --->spi_imx_transfer:1154 len:115200 [spi_dma t00]

[   71.813939] --->spi_imx_transfer:1157 len:115200 [spi_dma t01]

Test write......

#[   72.726856] --->spi_imx_transfer:1154 len:115200 [spi_dma t00]

[   72.832990] --->spi_imx_transfer:1157 len:115200 [spi_dma t01]

传输数据长度=240x240x2=115200 240x240为lcd屏宽x高 一个像素rgb565=2 bytes

通过前面时间戳计算一帧传输耗时:756468-656193=100275us=100ms=10Hz 

多组计算取均值fps:8.5

dma平均fps:8.5

2. 普通模式测试

insmod lcd_st7789.ko use_dma_flag=0

./test_spi_lcd_st7789 /dev/fb2

Test drawing RED......

data 0x000000f8

[  154.758112] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  154.764102] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  154.869715] --->spi_imx_transfer:1166 len:49665[spi_pio t01]

Test drawing GREEN......

data 0xffffe007

[  155.627946] --->spi_imx_transfer:1163 len:65535[spi_pio t00] #一帧开始

[  155.782548] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  155.788514] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  155.893319] --->spi_imx_transfer:1166 len:49665[spi_pio t01] #一帧结束

Test drawing BLUE......

data 0x00001f00

[  156.646880] --->spi_imx_transfer:1163 len:65535[spi_pio t00]

[  156.785073] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  156.790957] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  156.895981] --->spi_imx_transfer:1166 len:49665[spi_pio t01]

Test drawing WHITE......

data 0xffffffff

[  157.665533] --->spi_imx_transfer:1163 len:65535[spi_pio t00]

[  157.819960] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  157.825955] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  157.931670] --->spi_imx_transfer:1166 len:49665[spi_pio t01]

Test drawing Black......

data 0x00000000

[  158.684833] --->spi_imx_transfer:1163 len:65535[spi_pio t00]

[  158.843126] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  158.849013] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  158.955808] --->spi_imx_transfer:1166 len:49665[spi_pio t01]

Test write......

#[  159.697439] --->spi_imx_transfer:1163 len:65535[spi_pio t00]

[  159.857060] --->spi_imx_transfer:1166 len:65535[spi_pio t01]

[  159.863748] --->spi_imx_transfer:1163 len:49665[spi_pio t00]

[  159.967410] --->spi_imx_transfer:1166 len:49665[spi_pio t01]

115200= 65535+49665,通过dma类似方法算出平均fps

普通模式平均fps:3.71

3. 测试结果分析

dma 传输模式速度为普通模式的2.29倍,大大加速了数据传播速度

测试还发现dma_split_size 会影响dma的速度,越大dma传输会越快

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值