W800 W801 W806 SDIO的SPI模式驱动TFT LCD 突破低速SPI的20M限制 高达120M的SPI

W806 W800 W801 SDIO的SPI模式驱动TFTLCD

/***************************************************************************** 
* 
* File Name : main.c
* 
* Description: main 
* 
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd. 
* All rights reserved. 
* 
* Author : dave
* 
* Date : 2014-6-14
*****************************************************************************/ 

#include "wm_include.h"
#include "wm_gpio_afsel.h"
#include "wm_pmu.h"
#include "wm_sdio_host.h"
#include "wm_cpu.h"
#include "wm_dma.h"
#include "string.h"
#include "wm_uart.h"
#include "FreeRTOS.h"
#include "rtoslist.h"
#include "rtosqueue.h"
int wm_sd_card_dma_config(u32*mbuf,u32 bufsize,u8 dir);
    void delay_cnt(int count);

//#include <new>
//#include "protocal.h"
//#include <functional>

static int sm_sdh_wait_interrupt(uint8_t srcbit, int timeout)
{
    int ret = 0;
    unsigned int tmp = (1 << srcbit);
    volatile int vtimeout= timeout;

    if(vtimeout == -1) {
        vtimeout = 0x7FFFF;
    }

    while(1)
    {
        if(SDIO_HOST->MMC_INT_SRC & tmp)
        {
            SDIO_HOST->MMC_INT_SRC |= tmp;
            if(SDIO_HOST->MMC_INT_SRC)
            {
                printf("Err Int 0x%x\n", SDIO_HOST->MMC_INT_SRC);
            }
            break;
        }
        vtimeout--;
        if((vtimeout == 0) || (vtimeout < 0))
        {
            ret = 1; //timeout, err
            break;
        }
        delay_cnt(1);
    }
    return ret;
}

static const uint8_t st7789_init_seq[] = {
        1, 20, 0x01,                         // Software reset
        1, 10, 0x11,                         // Exit sleep mode
        2, 2, 0x3a, 0x55,                   // Set colour mode to 16 bit
        2, 0, 0x36, 0x00,                   // Set MADCTL: row then column, refresh is bottom to top ????
        5, 0, 0x2a, 0x00, 0x00, 0x00, 0xf0, // CASET: column addresses from 0 to 240 (f0)
        5, 0, 0x2b, 0x00, 0x00, 0x01, 0x40, // RASET: row addresses from 0 to 240 (f0)
        1, 2, 0x21,                         // Inversion on, then 10 ms delay (supposedly a hack?)
        1, 2, 0x13,                         // Normal display on, then 10 ms delay
        1, 2, 0x29,                         // Main screen turn on, then wait 500 ms
        0                                     // Terminate list
};

#define PIN_CS      WM_IO_PA_11
#define PIN_DC      WM_IO_PA_12
#define PIN_RESET   WM_IO_PA_13

static inline void lcd_set_dc_cs(bool dc, bool cs) {
    tls_gpio_write(PIN_DC, dc);
    tls_gpio_write(PIN_CS, cs);
}
static inline void st7789_lcd_wait_idle(){

}
static inline void st7789_lcd_put(u8 d){
    SDIO_HOST->BUF_CTL = 0x4820;
    SDIO_HOST->DATA_BUF[0] = d;

    SDIO_HOST->MMC_BYTECNTL = 1;
    SDIO_HOST->MMC_IO = 0x01;
    while (1) {
        if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
            break;
    }
}
static inline void lcd_write_cmd(const uint8_t *cmd, size_t count) {
    st7789_lcd_wait_idle();
    lcd_set_dc_cs(0, 0);
    st7789_lcd_put(*cmd++);
    if (count >= 2) {
        st7789_lcd_wait_idle();
        lcd_set_dc_cs(1, 0);
        for (size_t i = 0; i < count - 1; ++i)
            st7789_lcd_put( *cmd++);
    }
    st7789_lcd_wait_idle();
    lcd_set_dc_cs(1, 1);
}

static inline void lcd_init(const uint8_t *init_seq) {

    const uint8_t *cmd = init_seq;
    while (*cmd) {
        lcd_write_cmd(cmd + 2, *cmd);
        tls_os_time_delay(*(cmd + 1) * 5/2);
        cmd += *cmd + 2;
    }
}

static inline void st7789_start_pixels() {
    uint8_t cmd = 0x2c; // RAMWR
    lcd_write_cmd( &cmd, 1);
    lcd_set_dc_cs(1, 0);
}

static inline void init_sdio_spimode(){

    tls_io_cfg_set(WM_IO_PA_09, WM_IO_OPTION1);/*CK*/
    tls_io_cfg_set(WM_IO_PA_10, WM_IO_OPTION1);/*CMD*/

    tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_SDIO_MASTER);


    tls_bitband_write(HR_CLK_RST_CTL, 27, 0);

    tls_bitband_write(HR_CLK_RST_CTL, 27, 1);
    while (tls_bitband_read(HR_CLK_RST_CTL, 27) == 0);

    tls_sys_clk sysclk;

    tls_sys_clk_get(&sysclk);
    SDIO_HOST->MMC_CARDSEL = 0xC0 | (sysclk.cpuclk / 2 - 1);//0xd3; //enable module, enable mmcclk
    SDIO_HOST->MMC_CTL = 0x542 | 0 << 3;//0xC3; //4bits, low speed, 1/4 divider, auto transfer, mmc mode.
    SDIO_HOST->MMC_INT_MASK = 0x100; //unmask sdio data interrupt.
    SDIO_HOST->MMC_CRCCTL = 0x00; //
    SDIO_HOST->MMC_TIMEOUTCNT = 0;
    SDIO_HOST->MMC_BYTECNTL = 0;

}
void writetest(){
    int block_cnt = 1;
    int datalen=512 * block_cnt;
    SDIO_HOST->BUF_CTL = 0x4820;
    for (int i = 0; i < 128; i++)
        SDIO_HOST->DATA_BUF[i] = i;

    SDIO_HOST->MMC_BYTECNTL = datalen;
    tls_gpio_write(WM_IO_PB_08, 0);
    SDIO_HOST->MMC_IO = 0x01;
    while (1) {
        if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
            break;
    }
    tls_gpio_write(WM_IO_PB_08, 1);
}
void writetestDMA() {
    int block_cnt = 1;
    int datalen=512 * block_cnt;
    u32 *buf = (u32 *) tls_mem_alloc(datalen);
    for (int i = 0; i < datalen ; i++)
        ((uint8_t*)buf)[i] = i&0xff;
    SDIO_HOST->BUF_CTL = 0x4000; //disable dma,
    int dma_channel = wm_sd_card_dma_config((u32 *) buf, datalen, 1);
    SDIO_HOST->BUF_CTL = 0xC20; //enable dma, write sd card
    SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly

    tls_gpio_write(WM_IO_PB_08, 0);
    SDIO_HOST->MMC_BYTECNTL = datalen;
    SDIO_HOST->MMC_IO = 0x01;
    while (1) {
        if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
            break;
    }
    tls_gpio_write(WM_IO_PB_08, 1);
    tls_dma_free(dma_channel);
}
int wm_sd_card_dma_config__(u32*mbuf,u32 bufsize,u8 dir)
{
    int ch;
    u32 addr_inc = 0;

    ch = tls_dma_request(0, NULL);
    DMA_CHNLCTRL_REG(ch) = DMA_CHNL_CTRL_CHNL_OFF;

    if(dir)
    {
        DMA_SRCADDR_REG(ch) = (unsigned int)mbuf;
        DMA_DESTADDR_REG(ch) = (unsigned int)SDIO_HOST->DATA_BUF;
        addr_inc = DMA_CTRL_SRC_ADDR_INC;
    }
    else
    {
        DMA_SRCADDR_REG(ch) = (unsigned int)SDIO_HOST->DATA_BUF;
        DMA_DESTADDR_REG(ch) = (unsigned int)mbuf;
        addr_inc =DMA_CTRL_DEST_ADDR_INC;
    }
//    u32 mode=DMA_CTRL_DATA_SIZE_BYTE;
//    if(bufsize&1==0){
//        mode=DMA_CTRL_DATA_SIZE_SHORT;
//        if(bufsize&2==0)
//            mode=DMA_CTRL_DATA_SIZE_WORD;
//    }


    DMA_CTRL_REG(ch) = addr_inc | DMA_CTRL_DATA_SIZE_WORD | (bufsize << 8);
    DMA_MODE_REG(ch) = DMA_MODE_SEL_SDIOHOST | DMA_MODE_HARD_MODE;
    DMA_CHNLCTRL_REG(ch) = DMA_CHNL_CTRL_CHNL_ON;

    return ch;
}
void write_SDIO_SPI_DMA(u32* data,int len) {
    while (1) {
        if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
            break;
    }
    u32 offset=0;
    while(len>0){
        int datalen=len;
        if(len>0xfffc)
            datalen=0xfffc;
        len-=datalen;

        SDIO_HOST->BUF_CTL = 0x4000; //disable dma,
        int dma_channel = wm_sd_card_dma_config__((u32 *) data+offset, datalen, 1);
        SDIO_HOST->BUF_CTL = 0xC20; //enable dma, write sd card
        SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
        SDIO_HOST->MMC_BYTECNTL = datalen;
        SDIO_HOST->MMC_IO = 0x01;
        offset+=datalen/4;
        while (1) {
            if ((SDIO_HOST->BUF_CTL & 0x400) == 0x00)
                break;
        }
        tls_dma_free(dma_channel);
    }






}


//#define WHITE         	 0xFFFF
//#define BLACK         	 0x0000	  
//#define BLUE         	 0x001F  
//#define BRED             0XF81F
//#define GRED 			 0XFFE0
//#define GBLUE			 0X07FF
//#define RED           	 0xF800
//#define MAGENTA       	 0xF81F
//#define GREEN         	 0x07E0
//#define CYAN          	 0x7FFF
//#define YELLOW        	 0xFFE0
//#define BROWN 			 0XBC40 //棕色
//#define BRRED 			 0XFC07 //棕红色
//#define GRAY  			 0X8430 //灰色



void UartMain(void)
{
    printf("\n uart task \n");
    tls_gpio_cfg(PIN_CS, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
    tls_gpio_write(PIN_CS, 1);
    tls_gpio_cfg(PIN_DC, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
    tls_gpio_write(PIN_DC, 1);
    tls_gpio_cfg(PIN_RESET, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
    tls_gpio_write(PIN_RESET, 0);
	
	 tls_gpio_cfg(WM_IO_PA_08, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
    tls_gpio_write(WM_IO_PA_08, 1);
	
	
    tls_os_time_delay(100);
    tls_gpio_write(PIN_RESET, 1);
    init_sdio_spimode();
    lcd_init(st7789_init_seq);
    static u32 buf[240*120];
    int count=0;
	u16 buff[]={WHITE,BLACK,BLUE,BRED,GRED,YELLOW,RED,GRAY};
    while (1) {
        if(++count>=7)
		{
			count = 0;
		}
        u16*buf1=(u16*)buf;
        st7789_start_pixels();
        for (int x=0;x<240;x++)
            for(int y=0;y<240;y++){
               // buf1[y*320+x]=(((x+count)&0x1f)<<11)|(((y+count)&0x3f)<<5)|(((x+y+count)&0x1f));
				buf1[y*240+x]=buff[count];
            }
        write_SDIO_SPI_DMA((u32*)buf1,240*240*2);
		tls_os_time_delay(1000);
//        write_SDIO_SPI_DMA((u32*)buf1,240*240);
    }
}
void UserMain(void)
{
	printf("\n User task \n");
	
	tls_os_task_t uarttask;
	void* uartstack=malloc(16384);
	tls_os_task_create(&uarttask, "UartMain",
		   UartMain,
		   (void *)NULL,
		   (u8 *)uartstack,          /* 任务栈的起始地址 */
		   16384, /* 任务栈的大小     */
		   3,
		   0);
}

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoRuiYiQi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值