瀏覽代碼

add:尝试添加sdio的spi模式,暂不可用

Dozingfiretruck 3 年之前
父節點
當前提交
66e20ae3e9
共有 3 個文件被更改,包括 90 次插入1 次删除
  1. 31 1
      app/port/luat_spi_air101.c
  2. 3 0
      include/driver/wm_sdio_host.h
  3. 56 0
      platform/drivers/sdio_host/wm_sdio_host.c

+ 31 - 1
app/port/luat_spi_air101.c

@@ -4,18 +4,25 @@
 #include "luat_spi.h"
 
 #include "wm_include.h"
-
+#include "wm_sdio_host.h"
 #include "wm_hostspi.h"
 #include "wm_gpio_afsel.h"
 #include "wm_cpu.h"
+#include "wm_dma.h"
+#include "wm_pmu.h"
 
 #define LUAT_LOG_TAG "luat.spi"
 #include "luat_log.h"
 #include "luat_timer.h"
 
+
 static uint8_t luat_spi_mode = 1;
 
 int luat_spi_device_config(luat_spi_device_t* spi_dev) {
+    if (spi_dev->bus_id == 5){
+        sdio_spi_init(spi_dev->spi_config.bandrate);
+        return 0;
+    }
     unsigned int clk;
     uint8_t TLS_SPI_MODE = 0x00 ;
     clk = spi_dev->spi_config.bandrate;
@@ -53,6 +60,13 @@ int luat_spi_bus_setup(luat_spi_device_t* spi_dev){
 	    wm_spi_di_config(WM_IO_PB_25);
 	    wm_spi_do_config(WM_IO_PB_26);
     }
+    else if (bus_id == 5) {
+        tls_io_cfg_set(WM_IO_PB_06, WM_IO_OPTION2);/*CK*/
+        tls_io_cfg_set(WM_IO_PB_07, WM_IO_OPTION2);/*CMD*/
+        tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION2);/*D0*/
+        tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_SDIO_MASTER);
+        return 0;
+    }
     // #endif
     else{
         LLOGD("spi_bus error");
@@ -95,6 +109,17 @@ int luat_spi_setup(luat_spi_t* spi) {
 	    wm_spi_di_config(WM_IO_PB_25);
 	    wm_spi_do_config(WM_IO_PB_26);
     }
+    else if (spi->id == 5) {
+        if (spi->cs == 0 || spi->cs == WM_IO_PB_23)
+	        wm_spi_cs_config(WM_IO_PB_23);
+        tls_io_cfg_set(WM_IO_PB_06, WM_IO_OPTION2);/*CK*/
+        tls_io_cfg_set(WM_IO_PB_07, WM_IO_OPTION2);/*CMD*/
+        tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION2);/*D0*/
+        tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_SDIO_MASTER);
+
+        sdio_spi_init(spi->bandrate);
+        return 0;
+    }
     // #endif
     else {
         return -1;
@@ -163,6 +188,11 @@ int luat_spi_recv(int spi_id, char* recv_buf, size_t length) {
 //发SPI数据,返回发送字节数
 int luat_spi_send(int spi_id, const char* send_buf, size_t length) {
     int ret;
+    if (spi_id==5){
+        ret = sdio_spi_send(send_buf, length);
+        return ret?-1:length;
+    }
+    
     if(length <= SPI_DMA_BUF_MAX_SIZE)
     {
         ret = tls_spi_write(send_buf, length);

+ 3 - 0
include/driver/wm_sdio_host.h

@@ -130,6 +130,9 @@ int wm_sd_card_blocks_read(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t b
  */
 int wm_sd_card_blocks_write(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t buflen);
 
+void sdio_spi_init(u32 fclk);
+int sdio_spi_send(const u8 * buf, u32 len);
+
 /**
  * @}
  */

+ 56 - 0
platform/drivers/sdio_host/wm_sdio_host.c

@@ -756,3 +756,59 @@ end:
 	return ret;
 }
 
+void sdio_spi_init(u32 fclk){
+	sdio_host_reset();
+	tls_sys_clk sysclk;	
+	tls_sys_clk_get(&sysclk);
+	SDIO_HOST->MMC_CARDSEL = 0xC0 | (sysclk.cpuclk / 2 - 1);
+	uint8_t ti= sysclk.cpuclk / 2 / fclk;
+	SDIO_HOST->MMC_CTL = 0x542 | (ti << 3);
+	SDIO_HOST->MMC_CTL = 0x542;
+	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;
+}
+
+int sdio_spi_send(const u8 * buf, u32 len){
+    if ((buf == NULL) || (len == 0)){
+        return -1;
+    }
+    if (len < 4) {          // 直接传输,这样做的原因是DMA不能连续传输少于4个字节的数据
+        SDIO_HOST->BUF_CTL = 0x4820;
+        SDIO_HOST->DATA_BUF[0] = *((u32 *)buf);
+        SDIO_HOST->MMC_BYTECNTL = len;
+        SDIO_HOST->MMC_IO = 0x01;
+		while (1) {
+			if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
+				break;
+		}
+    } else {                   // DMA传输
+		u32 sendlen,txlen;
+		txlen = len & 0xfffffffc;   // 不够字的最后单独发
+		sendlen = txlen/4;
+		SDIO_HOST->BUF_CTL = 0x4000; //disable dma,
+		unsigned char sdio_spi_dma_channel = wm_sd_card_dma_config((u32 *) buf, sendlen, 1);
+		SDIO_HOST->BUF_CTL = 0xC20; //enable dma, write sd card
+		SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
+		SDIO_HOST->MMC_BYTECNTL = txlen;
+		SDIO_HOST->MMC_IO = 0x01;
+		tls_dma_free(sdio_spi_dma_channel);
+        while(1){
+            if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
+                break;
+        }
+		if (len > txlen){
+			SDIO_HOST->BUF_CTL = 0x4820;
+			SDIO_HOST->DATA_BUF[0] = *((u32 *)buf + sendlen);
+			SDIO_HOST->MMC_BYTECNTL = len-txlen;
+			SDIO_HOST->MMC_IO = 0x01;
+			while (1) {
+				if ((SDIO_HOST->MMC_IO & 0x01) == 0x00)
+					break;
+			}
+		}
+    }
+    return 0;
+}
+