2024-08-15 调试中发现 linux spi 驱动通过spi_write 或者 spi_sync 最多只能写0XFFFF 个字节,提供解决方案。

一、调试中发现,linux spi 驱动通过spi_write 或者 spi_sync 最多只能写0XFFFF 个字节。

二、在 Linux 的 SPI 驱动中,通过 spi_writespi_sync 函数传输数据时,数据传输的大小通常受到一些底层实现和协议限制的影响。在 SPI 子系统中,一次传输的数据大小可能最多为 0xFFFF(65535)字节。

三、解决方案。

int spi_send_large_data(struct spi_device *spi, const u8 *data, size_t len) {
    size_t chunk_size = 0xFFFF; // 每次传输的最大数据量
    int ret = 0;

    while (len > 0) {
        size_t transfer_size = min(len, chunk_size);
        ret = spi_write(spi, data, transfer_size);
        if (ret < 0) {
            return ret; // 传输失败,返回错误码
        }
        data += transfer_size;
        len -= transfer_size;
    }

    return 0; // 成功
}

四、然后我需要写的数据大于0XFFFF,只能优化代码。

static int nv3030b_write_image(struct nv3030b_data *pdata,struct spi_device *spi,u8 *data, int len)
{
    int n,total = 0,remain = len;
	gpiod_set_value(pdata->dc_gpio,1);
    while(remain > 0)
    {
	  n = remain > 0XFFFF ? 0XFFFF: remain;
	  if (spi_write(spi, data + total, n) < 0) {
		printk(KERN_ERR "SPI sync failed\n");
		return -EIO;
	  }
	  total = n + total;
	  remain = remain - n;
    }
	return total;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用SPI驱动TFT-LCD显示字符的代码: ```c #include "gd32f30x.h" #define TFT_CS_PIN GPIO_PIN_4 #define TFT_CS_PORT GPIOB #define TFT_DC_PIN GPIO_PIN_5 #define TFT_DC_PORT GPIOB #define SPIx SPI1 void TFT_WriteCommand(uint8_t cmd) { gpio_bit_write(TFT_DC_PORT, TFT_DC_PIN, 0); // DC = 0, 发送命令 spi_i2s_data_transmit(SPIx, cmd); while (spi_i2s_flag_get(SPIx, SPI_FLAG_TBE) == RESET); } void TFT_WriteData(uint8_t data) { gpio_bit_write(TFT_DC_PORT, TFT_DC_PIN, 1); // DC = 1, 发送数据 spi_i2s_data_transmit(SPIx, data); while (spi_i2s_flag_get(SPIx, SPI_FLAG_TBE) == RESET); } void TFT_Init(void) { spi_parameter_struct spi_init_struct; rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_SPI1); gpio_init(TFT_CS_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_CS_PIN); gpio_init(TFT_DC_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_DC_PIN); spi_i2s_deinit(SPIx); spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.device_mode = SPI_MASTER; spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; spi_init_struct.nss = SPI_NSS_SOFT; spi_init_struct.prescale = SPI_PSC_2; spi_init_struct.endian = SPI_ENDIAN_MSB; spi_init(SPIx, &spi_init_struct); spi_enable(SPIx); gpio_bit_write(TFT_CS_PORT, TFT_CS_PIN, 0); // CS = 0, 选TFT-LCD TFT_WriteCommand(0x01); // SWRESET delay_1ms(10); TFT_WriteCommand(0x11); // SLPOUT delay_1ms(120); TFT_WriteCommand(0x3A); // COLMOD TFT_WriteData(0x05); // 16-bit color TFT_WriteCommand(0x36); // MADCTL TFT_WriteData(0xC0); // Set rotation TFT_WriteCommand(0xB1); // Frame rate control TFT_WriteData(0x01); TFT_WriteData(0x2C); TFT_WriteData(0x2D); TFT_WriteCommand(0xB2); // Analog setting TFT_WriteData(0x01); TFT_WriteData(0x11); TFT_WriteCommand(0xB3); // Enable PT TFT_WriteData(0x00); TFT_WriteCommand(0xC0); // Power control TFT_WriteData(0x10); TFT_WriteCommand(0xC5); // VCOM control TFT_WriteData(0x3E); TFT_WriteData(0x28); TFT_WriteCommand(0xC8); // GAMMA control TFT_WriteData(0x00); TFT_WriteData(0x06); TFT_WriteData(0x07); TFT_WriteData(0x01); TFT_WriteData(0x99); TFT_WriteData(0x00); TFT_WriteCommand(0xD0); // Power control TFT_WriteData(0x7F); TFT_WriteData(0x0D); TFT_WriteCommand(0xE0); // PGAMMA control TFT_WriteData(0x0F); TFT_WriteData(0x1F); TFT_WriteData(0x1C); TFT_WriteData(0x0C); TFT_WriteData(0x0F); TFT_WriteData(0x08); TFT_WriteData(0x48); TFT_WriteData(0x98); TFT_WriteData(0x37); TFT_WriteData(0x0A); TFT_WriteData(0x13); TFT_WriteData(0x04); TFT_WriteData(0x11); TFT_WriteData(0x0D); TFT_WriteData(0x00); TFT_WriteCommand(0xE1); // NGAMMA control TFT_WriteData(0x0F); TFT_WriteData(0x32); TFT_WriteData(0x2E); TFT_WriteData(0x0B); TFT_WriteData(0x0D); TFT_WriteData(0x05); TFT_WriteData(0x47); TFT_WriteData(0x75); TFT_WriteData(0x37); TFT_WriteData(0x06); TFT_WriteData(0x10); TFT_WriteData(0x03); TFT_WriteData(0x24); TFT_WriteData(0x20); TFT_WriteData(0x00); TFT_WriteCommand(0x29); // DISPON } void TFT_SetWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { TFT_WriteCommand(0x2A); // CASET TFT_WriteData(x1 >> 8); TFT_WriteData(x1 & 0xFF); TFT_WriteData(x2 >> 8); TFT_WriteData(x2 & 0xFF); TFT_WriteCommand(0x2B); // RASET TFT_WriteData(y1 >> 8); TFT_WriteData(y1 & 0xFF); TFT_WriteData(y2 >> 8); TFT_WriteData(y2 & 0xFF); TFT_WriteCommand(0x2C); // RAMWR } void TFT_DrawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg_color, uint8_t size) { uint8_t i, j; if ((x >= 240) || (y >= 320) || ((x + 6 * size - 1) < x) || ((y + 8 * size - 1) < y)) { return; } for (i = 0; i < 6; i++) { uint8_t line; if (i == 5) { line = 0x0; } else { line = font[c * 5 + i]; } for (j = 0; j < 8; j++) { if (line & 0x1) { if (size == 1) { TFT_DrawPixel(x + i, y + j, color); } else { TFT_FillRect(x + (i * size), y + (j * size), size, size, color); } } else if (bg_color != color) { if (size == 1) { TFT_DrawPixel(x + i, y + j, bg_color); } else { TFT_FillRect(x + i * size, y + j * size, size, size, bg_color); } } line >>= 1; } } } void TFT_DrawString(uint16_t x, uint16_t y, char *str, uint16_t color, uint16_t bg_color, uint8_t size) { while (*str) { TFT_DrawChar(x, y, *str++, color, bg_color, size); x += 6 * size; } } void TFT_DrawPixel(uint16_t x, uint16_t y, uint16_t color) { TFT_SetWindow(x, y, x, y); TFT_WriteData(color >> 8); TFT_WriteData(color & 0xFF); } void TFT_FillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { uint16_t i, j; for (i = x; i < x + w; i++) { for (j = y; j < y + h; j++) { TFT_DrawPixel(i, j, color); } } } int main(void) { TFT_Init(); while (1) { TFT_DrawString(20, 20, "Hello World!", 0xFFFF, 0x0000, 2); delay_1ms(1000); TFT_FillRect(20, 20, 12 * 12, 2 * 16, 0x0000); delay_1ms(1000); } } ``` 需要注意的是,这里使用的是一个5x7像素的字体库,可以自行替换成其他字体库。另外,需要根据具体的TFT-LCD型号,修改初始化函数的一些命令和参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值