Просмотр исходного кода

update:加快了BL下载速度,优化休眠功耗,修复spi读tf卡,USB HID上传回车符
fix:spi在阻塞和非阻塞来回切换卡死

alienwalker 3 лет назад
Родитель
Сommit
0dae6cac55

+ 1 - 0
application/include/app_interface.h

@@ -35,6 +35,7 @@
 #include "core_spi.h"
 #include "core_wdt.h"
 #include "core_rtc.h"
+#include "core_pm.h"
 #include "core_hwtimer.h"
 #include "core_service.h"
 #include "core_keyboard.h"

+ 3 - 3
application/include/luat_conf_bsp.h

@@ -23,7 +23,7 @@
 #ifndef LUAT_CONF_BSP
 #define LUAT_CONF_BSP
 
-#define LUAT_BSP_VERSION "V0004"
+#define LUAT_BSP_VERSION "V0005"
 
 
 #define LUAT_USE_FS_VFS 1
@@ -37,7 +37,7 @@
 #define LUAT_USE_ADC  1
 #define LUAT_USE_PWM  1
 #define LUAT_USE_WDT  1
-// #define LUAT_USE_PM  1
+#define LUAT_USE_PM  1
 #define LUAT_USE_MCU  1
 // #define LUAT_USE_HWTIMER  1
 #define LUAT_USE_RTC 1
@@ -57,7 +57,7 @@
 #define LUAT_USE_SFD  1
 // #define LUAT_USE_STATEM 1
 // #define LUAT_USE_COREMARK 1
-// #define LUAT_USE_FDB 1
+#define LUAT_USE_FDB 1
 // #define LUAT_USE_ZLIB 
 #define LUAT_USE_CAMERA  1
 #define LUAT_USE_FATFS 1

+ 3 - 3
application/src/luat_base_air105.c

@@ -96,9 +96,9 @@ static const luaL_Reg loadedlibs[] = {
 #ifdef LUAT_USE_WDT
   {"wdt",     luaopen_wdt},               // watchdog模块
 #endif
-// #ifdef LUAT_USE_PM
-//   {"pm",      luaopen_pm},                // 电源管理模块
-// #endif
+#ifdef LUAT_USE_PM
+  {"pm",      luaopen_pm},                // 电源管理模块
+#endif
 #ifdef LUAT_USE_MCU
   {"mcu",     luaopen_mcu},               // MCU特有的一些操作
 #endif

+ 7 - 6
application/src/luat_camera_air105.c

@@ -86,6 +86,7 @@ static int32_t Camera_SaveJPEGDone(void *pData, void *pParam)
 		LLOGD("capture data %ubyte", luat_fs_fwrite(prvCamera.FileBuffer.Data, prvCamera.FileBuffer.Pos, 1, fd));
 		luat_fs_fclose(fd);
 	}
+
 	OS_DeInitBuffer(&prvCamera.FileBuffer);
 	prvCamera.CaptureWait = 1;
 	prvCamera.JPEGEncodeDone = 1;
@@ -120,17 +121,17 @@ static int32_t Camera_DrawLcd(void *DrawData, uint8_t Scan){
         DBG("lcd flush no memory");
         return -1;
     }
-    uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPHA;
-    uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPOL;
+    uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPHA;
+    uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.CPOL;
     draw->DCDelay = lcd_conf->dc_delay_us;
     draw->Mode = SPI_MODE_0;
     if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
     else if(CPOL)draw->Mode = SPI_MODE_2;
     else if(CPHA)draw->Mode = SPI_MODE_1;
-    draw->Speed = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.bandrate;
-    if (((luat_spi_device_t*)(lcd_conf->userdata))->bus_id == 5) draw->SpiID = HSPI_ID0;
-    else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->userdata))->bus_id;
-    draw->CSPin = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.cs;
+    draw->Speed = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.bandrate;
+    if (((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id == 5) draw->SpiID = HSPI_ID0;
+    else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->bus_id;
+    draw->CSPin = ((luat_spi_device_t*)(lcd_conf->lcd_spi_device))->spi_config.cs;
     draw->DCPin = lcd_conf->pin_dc;
     draw->xoffset = lcd_conf->xoffset;
     draw->yoffset = lcd_conf->yoffset;

+ 66 - 0
application/src/luat_pm_air105.c

@@ -0,0 +1,66 @@
+#include "luat_base.h"
+#include "luat_pm.h"
+#include "app_interface.h"
+
+#define LUAT_LOG_TAG "pm"
+#include "luat_log.h"
+
+int luat_pm_request(int mode) {
+    if (mode != LUAT_PM_SLEEP_MODE_LIGHT || mode == LUAT_PM_SLEEP_MODE_DEEP) {
+        LLOGW("only pm.LIGHT/pm.DEEP supported");
+        return -1;
+    }
+    uint8_t i;
+//    for(i = UART_ID1; i< UART_MAX; i++)
+//    {
+//    	Uart_Sleep(i, 0);
+//    }
+    PM_SetDriverRunFlag(PM_DRV_DBG, 0);
+    return 0;
+}
+
+int luat_pm_release(int mode) {
+    return 0;
+}
+
+int luat_pm_dtimer_start(int id, size_t timeout) {
+    if (id != 0)
+        return -1;
+    RTC_SetAlarm(timeout / 1000, NULL, NULL); // 无需回调, 或者改成回调里重启, 也不太对的样
+    return 0;
+}
+
+int luat_pm_dtimer_stop(int id) {
+    if (id != 0)
+        return -1;
+    RTC_SetAlarm(0, NULL, NULL); // 设置为0就是关闭
+    return 0;
+}
+
+int luat_pm_dtimer_check(int id) {
+    return -1;
+}
+
+// void luat_pm_cb(int event, int arg, void* args);
+
+int luat_pm_last_state(int *lastState, int *rtcOrPad) {
+    return 0;
+}
+
+int luat_pm_force(int mode) {
+    return luat_pm_request(mode);
+}
+
+int luat_pm_check(void) {
+    return 0;
+}
+
+int luat_pm_dtimer_list(size_t* count, size_t* list) {
+    *count = 0;
+    return 0;
+}
+
+int luat_pm_dtimer_wakeup_id(int* id) {
+    return -1;
+}
+

+ 108 - 4
application/src/luat_spi_air105.c

@@ -24,7 +24,8 @@
 #include "luat_base.h"
 #include "luat_spi.h"
 #include "luat_lcd.h"
-
+#include "ff.h"			/* Obtains integer types */
+#include "diskio.h"		/* Declarations of disk functions */
 #include "app_interface.h"
 
 #define LUAT_LOG_TAG "luat.spi"
@@ -151,7 +152,7 @@ int luat_spi_setup(luat_spi_t* spi) {
     else if(spi->CPOL)spi_mode = SPI_MODE_2;
     else if(spi->CPHA)spi_mode = SPI_MODE_1;
     luat_spi[spi_id].mode=spi->mode;
-    // LLOGD("SPI_MasterInit luat_spi%d:%d dataw:%d spi_mode:%d bandrate:%d ",spi_id,luat_spi[spi_id], spi->dataw, spi_mode, spi->bandrate);
+//    LLOGD("SPI_MasterInit luat_spi%d:%d dataw:%d spi_mode:%d bandrate:%d ",spi_id,luat_spi[spi_id].id, spi->dataw, spi_mode, spi->bandrate);
     SPI_MasterInit(luat_spi[spi_id].id, spi->dataw, spi_mode, spi->bandrate, luat_spi_cb, NULL);
     return 0;
 }
@@ -213,7 +214,7 @@ int luat_lcd_draw_no_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint
 			LLOGE("lcd flush no memory");
 			return -1;
 		}
-		luat_spi_device_t* spi_dev = (luat_spi_device_t*)conf->userdata;
+		luat_spi_device_t* spi_dev = (luat_spi_device_t*)conf->lcd_spi_device;
 		int spi_id = spi_dev->bus_id;
 	    uint8_t spi_mode = SPI_MODE_0;
 	    if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
@@ -254,7 +255,7 @@ void luat_lcd_draw_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint16
 {
 	LCD_DrawStruct draw;
 	if (conf->port == LUAT_LCD_SPI_DEVICE){
-		luat_spi_device_t* spi_dev = (luat_spi_device_t*)conf->userdata;
+		luat_spi_device_t* spi_dev = (luat_spi_device_t*)conf->lcd_spi_device;
 		int spi_id = spi_dev->bus_id;
 	    uint8_t spi_mode = SPI_MODE_0;
 	    if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
@@ -278,3 +279,106 @@ void luat_lcd_draw_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint16
 	    Core_LCDDrawBlock(&draw);
 	}
 }
+
+static void *luat_fatfs_spi_ctrl;
+
+static void sdhc_spi_check(luat_fatfs_spi_t* userdata)
+{
+	if (!luat_fatfs_spi_ctrl)
+	{
+		if(userdata->type == 1){
+			luat_fatfs_spi_ctrl = SDHC_SpiCreate(luat_spi[userdata->spi_device->bus_id].id, userdata->spi_device->spi_config.cs);
+			luat_spi_device_config(userdata->spi_device);
+		}else{
+			luat_fatfs_spi_ctrl = SDHC_SpiCreate(luat_spi[userdata->spi_id].id, userdata->spi_cs);
+		}
+	}
+}
+
+static DSTATUS sdhc_spi_initialize(luat_fatfs_spi_t* userdata)
+{
+	if (luat_fatfs_spi_ctrl)
+	{
+		free(luat_fatfs_spi_ctrl);
+		luat_fatfs_spi_ctrl = NULL;
+	}
+	sdhc_spi_check(userdata);
+	SDHC_SpiInitCard(luat_fatfs_spi_ctrl);
+	if(userdata->type == 1){
+		userdata->spi_device->spi_config.bandrate = userdata->fast_speed;
+		luat_spi_device_config(userdata->spi_device);
+	}else{
+		SPI_SetNewConfig(luat_spi[userdata->spi_id].id, userdata->fast_speed, 0);
+	}
+	return SDHC_IsReady(luat_fatfs_spi_ctrl)?0:STA_NOINIT;
+}
+
+static DSTATUS sdhc_spi_status(luat_fatfs_spi_t* userdata)
+{
+	sdhc_spi_check(userdata);
+	return SDHC_IsReady(luat_fatfs_spi_ctrl)?0:STA_NOINIT;
+}
+
+static DRESULT sdhc_spi_read(luat_fatfs_spi_t* userdata, uint8_t* buff, uint32_t sector, uint32_t count)
+{
+	sdhc_spi_check(userdata);
+	if (!SDHC_IsReady(luat_fatfs_spi_ctrl))
+	{
+		return RES_NOTRDY;
+	}
+	SDHC_SpiReadBlocks(luat_fatfs_spi_ctrl, buff, sector, count);
+	return SDHC_IsReady(luat_fatfs_spi_ctrl)?RES_OK:RES_ERROR;
+}
+
+static DRESULT sdhc_spi_write(luat_fatfs_spi_t* userdata, const uint8_t* buff, uint32_t sector, uint32_t count)
+{
+	sdhc_spi_check(userdata);
+	if (!SDHC_IsReady(luat_fatfs_spi_ctrl))
+	{
+		return RES_NOTRDY;
+	}
+	SDHC_SpiWriteBlocks(luat_fatfs_spi_ctrl, buff, sector, count);
+	return SDHC_IsReady(luat_fatfs_spi_ctrl)?RES_OK:RES_ERROR;
+}
+
+static DRESULT sdhc_spi_ioctl(luat_fatfs_spi_t* userdata, uint8_t ctrl, void* buff)
+{
+	sdhc_spi_check(userdata);
+	if (!SDHC_IsReady(luat_fatfs_spi_ctrl))
+	{
+		return RES_NOTRDY;
+	}
+	SDHC_SpiReadCardConfig(luat_fatfs_spi_ctrl);
+	switch (ctrl) {
+		case CTRL_SYNC :		/* Make sure that no pending write process */
+			return RES_OK;
+			break;
+
+		case GET_SECTOR_COUNT :	/* Get number of sectors on the disk (DWORD) */
+			*(uint32_t*)buff = SDHC_GetLogBlockNbr(luat_fatfs_spi_ctrl);
+			return RES_OK;
+			break;
+
+		case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
+			*(uint32_t*)buff = 128;
+			return RES_OK;
+			break;
+
+		default:
+			return RES_PARERR;
+	}
+	return RES_PARERR;
+}
+
+static const block_disk_opts_t sdhc_spi_disk_opts = {
+    .initialize = sdhc_spi_initialize,
+    .status = sdhc_spi_status,
+    .read = sdhc_spi_read,
+    .write = sdhc_spi_write,
+    .ioctl = sdhc_spi_ioctl,
+};
+
+void luat_spi_set_sdhc_ctrl(block_disk_t *disk)
+{
+	disk->opts = &sdhc_spi_disk_opts;
+}

+ 1 - 1
bsp/air105/chip/include/air105.h

@@ -215,7 +215,7 @@ typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
 #define BIT30       (0x40000000U)
 #define BIT31       (0x80000000U)
 
-#define BIT(n)      (1UL << (n))
+
 
 typedef struct
 {

+ 11 - 13
bsp/air105/hal/core_pm.c

@@ -17,15 +17,13 @@ void PM_Init(void)
 	GPIO->WAKE_P0_EN = 0;
 	GPIO->WAKE_P1_EN = 0;
 	GPIO->WAKE_P2_EN = 0;
-	SYSCTRL->MSR_CR1 |= BIT(27);
-	SYSCTRL->LDO25_CR |= BIT(4);
-	SYSCTRL->ANA_CTRL |= BIT(7)|BIT(4)|BIT(5);
 	SENSOR->SEN_EXTS_START = 0x55;
 	int i;
 	for(i = 0; i < 19; i++)
 	{
 		SENSOR->SEN_EN[i] = 0x80000055;
 	}
+	SYSCTRL->MSR_CR1 |= BIT(27);
 }
 
 void PM_SetHardwareRunFlag(uint32_t PmHWSn, uint32_t OnOff)
@@ -60,28 +58,28 @@ void PM_Print(void)
 int32_t PM_Sleep(void)
 {
 	uint64_t StartTick;
-	uint32_t Temp, Temp2, Temp3, Temp4;
+	uint32_t Temp;
 	if (prvPM.HWFlagBit || prvPM.DrvFlagBit) return -ERROR_DEVICE_BUSY;
 	__disable_irq();
-	Temp2 = ADC0->ADC_CR1;
-	Temp3 = DAC->DAC_CR1;
-	Temp4 = ADC0->ADC_CR2;
+	SYSCTRL->ANA_CTRL |= BIT(7)|BIT(5)|BIT(4);
+	SYSCTRL->LDO25_CR |= BIT(4);
 	ADC0->ADC_CR1 |= BIT(8);
 	ADC0->ADC_CR1 &= ~BIT(6);
-	DAC->DAC_CR1 |= (1 << 4);
-	ADC_IntelResistance(0);
+	DAC->DAC_CR1 |= BIT(4);
 	StartTick = RTC_GetUTC();
 	Temp = TRNG->RNG_ANA;
 	TRNG->RNG_ANA = Temp | TRNG_RNG_AMA_PD_ALL_Mask;
 //	SYSCTRL->PHER_CTRL |= BIT(20);
-//	SYSCTRL->LDO25_CR |= BIT(5);
+
 	__WFI();
 //	SYSCTRL->LDO25_CR &= ~BIT(5);
 //	SYSCTRL->PHER_CTRL &= ~BIT(20);
 	TRNG->RNG_ANA = Temp;
-	ADC0->ADC_CR1 = Temp2;
-	DAC->DAC_CR1 = Temp3;
-	ADC0->ADC_CR2 = Temp4;
+	ADC0->ADC_CR1 &= ~BIT(8);
+	ADC0->ADC_CR1 |= BIT(6);
+	DAC->DAC_CR1 &= ~BIT(4);
+	SYSCTRL->LDO25_CR &= ~BIT(4);
+    SYSCTRL->ANA_CTRL &= ~(BIT(7)|BIT(5)|BIT(4));
 	WDT_Feed();
 	SysTickAddSleepTime((RTC_GetUTC() - StartTick) * CORE_TICK_1S);
 	Timer_WakeupRun();

+ 14 - 1
bsp/air105/hal/core_spi.c

@@ -74,12 +74,14 @@ typedef struct
 	Buffer_Struct TxBuf;
 	Buffer_Struct RxBuf;
 	uint32_t Speed;
+	uint32_t TargetSpeed;
 	uint8_t DMATxStream;
 	uint8_t DMARxStream;
 	uint8_t Is16Bit;
 	uint8_t IsOnlyTx;
 	uint8_t IsBusy;
 	uint8_t IsBlockMode;
+	uint8_t SpiMode;
 }SPI_ResourceStruct;
 
 static SPI_ResourceStruct prvSPI[SPI_MAX] = {
@@ -173,6 +175,7 @@ static void HSPI_IrqHandle(int32_t IrqLine, void *pData)
 #ifdef __BUILD_OS__
 		if (prvSPI[SpiID].IsBlockMode)
 		{
+			prvSPI[SpiID].IsBlockMode = 0;
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
@@ -247,6 +250,7 @@ static int32_t SPI_DMADoneCB(void *pData, void *pParam)
 #ifdef __BUILD_OS__
 		if (prvSPI[SpiID].IsBlockMode)
 		{
+			prvSPI[SpiID].IsBlockMode = 0;
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
@@ -315,6 +319,7 @@ static void SPI_IrqHandle(int32_t IrqLine, void *pData)
 #ifdef __BUILD_OS__
 		if (prvSPI[SpiID].IsBlockMode)
 		{
+			prvSPI[SpiID].IsBlockMode = 0;
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
@@ -397,6 +402,8 @@ void SPI_MasterInit(uint8_t SpiID, uint8_t DataBit, uint8_t Mode, uint32_t Speed
 	SPI_TypeDef *SPI;
 	uint32_t ctrl;
 	uint32_t div;
+	prvSPI[SpiID].SpiMode = Mode;
+	prvSPI[SpiID].TargetSpeed = Speed;
 	switch(SpiID)
 	{
 	case HSPI_ID0:
@@ -1119,7 +1126,13 @@ void SPI_SetNewConfig(uint8_t SpiID, uint32_t Speed, uint8_t NewMode)
 	SPI_TypeDef *SPI;
 	uint32_t div;
 	if (prvSPI[SpiID].IsBusy) return;
-
+	if ((prvSPI[SpiID].TargetSpeed == Speed) && (prvSPI[SpiID].SpiMode == NewMode))
+	{
+		return;
+	}
+//	DBG("speed %u->%u mode %u->%u", prvSPI[SpiID].TargetSpeed, Speed, prvSPI[SpiID].SpiMode, NewMode);
+	prvSPI[SpiID].TargetSpeed = Speed;
+	prvSPI[SpiID].SpiMode == NewMode;
 	switch(SpiID)
 	{
 	case HSPI_ID0:

+ 3 - 2
bsp/air105/include/bl_inc.h

@@ -23,8 +23,8 @@
 #define __BL_INC_H__
 #include "global_config.h"
 #ifdef __AIR105_BSP__
-#include "../chip/include/air105.h"
-#include "../chip/include/air105_conf.h"
+#include "air105.h"
+#include "air105_conf.h"
 #endif
 #include "bsp_common.h"
 #include "platform_define.h"
@@ -53,5 +53,6 @@
 #include "usb_cdc.h"
 
 #include "dev_spiflash.h"
+#include "dev_sdhc_spi.h"
 #include "audio_ll_drv.h"
 #endif

+ 4 - 2
bsp/air105/include/resource_map.h

@@ -54,7 +54,9 @@
 #define LCD_SPI_TX_DMA_STREAM	DMA1_STREAM_6
 #define LCD_SPI_RX_DMA_STREAM	DMA1_STREAM_7
 
-#define LUATOS_TASK_PRO		(configMAX_PRIORITIES - 2)
+#define LUATOS_TASK_PRO		(configMAX_PRIORITIES - 4)
 #define HW_TASK_PRO		(configMAX_PRIORITIES - 1)
-#define SERVICE_TASK_PRO		(configMAX_PRIORITIES - 4)
+#define USB_TASK_PRO		(configMAX_PRIORITIES - 2)
+#define AUDIO_TASK_PRO		(configMAX_PRIORITIES - 3)
+#define SERVICE_TASK_PRO		(configMAX_PRIORITIES - 5)
 #endif

+ 2 - 2
bsp/air105/platform/app_main.c

@@ -64,10 +64,10 @@ void SystemInit(void)
 	SCB->VTOR = (uint32_t)(&__isr_start_address);
 	SYSCTRL->CG_CTRL1 = SYSCTRL_APBPeriph_ALL;
 	SYSCTRL->SOFT_RST1 = SYSCTRL_APBPeriph_ALL;
-	SYSCTRL->PHER_CTRL &= ~(1 << 20);
+	SYSCTRL->PHER_CTRL &= ~BIT(20);
     SYSCTRL->SOFT_RST2 &= ~SYSCTRL_USB_RESET;
     SYSCTRL->LOCK_R |= SYSCTRL_USB_RESET;
-    SYSCTRL->LDO25_CR &= ~BIT(5);
+    SYSCTRL->LDO25_CR &= ~(BIT(4)|BIT(5));
 //    BPU->SEN_ANA0 &= ~(1 << 10);
 #ifdef __USE_32K_XTL__
 	BPU->SEN_ANA0 |= (1 << 10)|(7 << 25) | (2 << 29);	//外部32768+最大充电电流+最大晶振供电

+ 9 - 5
bsp/common/include/bsp_common.h

@@ -139,12 +139,16 @@ enum
 	UART_CB_CONNECTED,	//串口工具对方已经打开
 	DMA_CB_ERROR = 0xffffffff,
 
-	CORE_EVENT_ID_START = 0,
+
 	CORE_EVENT_ID_ANY = 0,
+	CORE_EVENT_ID_START = 0xf0000000,
 	CORE_EVENT_TIMEOUT,
-	CORE_TIMER_TIMEOUT = 0x00010000,
-	SERVICE_EVENT_ID_START = 0x00100000,
-	USER_EVENT_ID_START = 0x10000000,
+	CORE_TIMER_TIMEOUT = 0xf0010000,
+	SERVICE_EVENT_ID_START = 0xf0100000,
+	DEV_EVENT_ID_START = 0xf0200000,
+	DEV_SPIFLASH_SPI_DONE,
+	DEV_SDHC_SPI_DONE,
+	USER_EVENT_ID_START = 0xf1000000,
 	INVALID_EVENT_ID = 0xffffffff,
 };
 
@@ -158,7 +162,7 @@ enum
 #define CRC16_IBM_SEED	(0xffff)
 #define CRC16_CCITT_SEED		(0x1D0F)
 #define HANDLE			void *
-
+#define BIT(n)      (1UL << (n))
 #define MIN(X,Y)	(((X) < (Y))?(X):(Y))
 
 typedef void (* TaskFun_t)( void * );

+ 32 - 23
bsp/common/src/core_usb_app.c

@@ -997,13 +997,12 @@ void Core_VHIDUploadData(uint8_t USB_ID, uint8_t *Data, uint16_t Len)
 			HIDKeyBoard.PressKey[0] = HIDKey.Value;
 //			DBG("%u,%c,%d,%x,%d", Pos - 1, Data[Pos - 1], 0, HIDKey.Value, HIDKey.Shift);
 ADD_REST:
-			for(i = 1; i < 4; i++)
+			for(i = 1; i < 6; i++)
 			{
 				HIDKey = USB_HIDGetValueFromAscii(Data[Pos]);
 				Pos++;
-				if ((IsShift != HIDKey.Shift))
+				if ((IsShift != HIDKey.Shift) || (LastValue == HIDKey.Value) || (LastValue == '\r') || (LastValue == '\n'))
 				{
-					//shift发生切换,必须换新的data
 					OS_BufferWrite(&pVHID->TxCacheBuf, &HIDKeyBoard, sizeof(HIDKeyBoard));
 					memset(&HIDKeyBoard, 0, sizeof(USB_HIDKeyBoradKeyStruct));
 					//加入一个抬起的data
@@ -1023,26 +1022,26 @@ ADD_REST:
 					}
 
 				}
-				else if (LastValue == HIDKey.Value)
-				{
-					OS_BufferWrite(&pVHID->TxCacheBuf, &HIDKeyBoard, sizeof(HIDKeyBoard));
-					memset(&HIDKeyBoard, 0, sizeof(USB_HIDKeyBoradKeyStruct));
-					//加入一个抬起的data
-					OS_BufferWrite(&pVHID->TxCacheBuf, &HIDKeyBoard, sizeof(HIDKeyBoard));
-					IsShift = HIDKey.Shift;
-					LastValue = HIDKey.Value;
-					HIDKeyBoard.SPECIALHID_KEY_b.RightShift = IsShift;
-					HIDKeyBoard.PressKey[0] = HIDKey.Value;
-//					DBG("%u,%c,%d,%x,%d", Pos - 1, Data[Pos - 1], 0, HIDKey.Value, HIDKey.Shift);
-					if (Pos < Len)
-					{
-						goto ADD_REST;
-					}
-					else
-					{
-						break;
-					}
-				}
+//				else if
+//				{
+//					OS_BufferWrite(&pVHID->TxCacheBuf, &HIDKeyBoard, sizeof(HIDKeyBoard));
+//					memset(&HIDKeyBoard, 0, sizeof(USB_HIDKeyBoradKeyStruct));
+//					//加入一个抬起的data
+//					OS_BufferWrite(&pVHID->TxCacheBuf, &HIDKeyBoard, sizeof(HIDKeyBoard));
+//					IsShift = HIDKey.Shift;
+//					LastValue = HIDKey.Value;
+//					HIDKeyBoard.SPECIALHID_KEY_b.RightShift = IsShift;
+//					HIDKeyBoard.PressKey[0] = HIDKey.Value;
+////					DBG("%u,%c,%d,%x,%d", Pos - 1, Data[Pos - 1], 0, HIDKey.Value, HIDKey.Shift);
+//					if (Pos < Len)
+//					{
+//						goto ADD_REST;
+//					}
+//					else
+//					{
+//						break;
+//					}
+//				}
 				else
 				{
 					LastValue = HIDKey.Value;
@@ -1087,3 +1086,13 @@ void Core_VHIDUploadStop(uint8_t USB_ID)
 	USB_StackStopDeviceTx(pVHID->USB_ID, pVHID->ToHostEpIndex, 0);
 	USB_StackEpIntOnOff(pVHID->USB_ID, pVHID->ToHostEpIndex, 0, 1);
 }
+
+static void prvUSB_AppTask(void *pParam)
+{
+
+}
+
+void USB_AppTaskInit(void)
+{
+
+}

+ 133 - 0
bsp/device/include/dev_sdhc_spi.h

@@ -0,0 +1,133 @@
+#ifndef __DEV_SDHC_SPI_H__
+#define __DEV_SDHC_SPI_H__
+
+#define __SDHC_BLOCK_LEN__	(512)
+
+typedef struct
+{
+  uint8_t  Reserved1:2;               /* Reserved */
+  uint16_t DeviceSize:12;             /* Device Size */
+  uint8_t  MaxRdCurrentVDDMin:3;      /* Max. read current @ VDD min */
+  uint8_t  MaxRdCurrentVDDMax:3;      /* Max. read current @ VDD max */
+  uint8_t  MaxWrCurrentVDDMin:3;      /* Max. write current @ VDD min */
+  uint8_t  MaxWrCurrentVDDMax:3;      /* Max. write current @ VDD max */
+  uint8_t  DeviceSizeMul:3;           /* Device size multiplier */
+} struct_v1;
+
+
+typedef struct
+{
+  uint8_t  Reserved1:6;               /* Reserved */
+  uint32_t DeviceSize:22;             /* Device Size */
+  uint8_t  Reserved2:1;               /* Reserved */
+} struct_v2;
+
+/**
+  * @brief  Card Specific Data: CSD Register
+  */
+typedef struct
+{
+  /* Header part */
+  uint8_t  CSDStruct:2;            /* CSD structure */
+  uint8_t  Reserved1:6;            /* Reserved */
+  uint8_t  TAAC:8;                 /* Data read access-time 1 */
+  uint8_t  NSAC:8;                 /* Data read access-time 2 in CLK cycles */
+  uint8_t  MaxBusClkFrec:8;        /* Max. bus clock frequency */
+  uint16_t CardComdClasses:12;      /* Card command classes */
+  uint8_t  RdBlockLen:4;           /* Max. read data block length */
+  uint8_t  PartBlockRead:1;        /* Partial blocks for read allowed */
+  uint8_t  WrBlockMisalign:1;      /* Write block misalignment */
+  uint8_t  RdBlockMisalign:1;      /* Read block misalignment */
+  uint8_t  DSRImpl:1;              /* DSR implemented */
+
+  /* v1 or v2 struct */
+  union csd_version {
+    struct_v1 v1;
+    struct_v2 v2;
+  } version;
+
+  uint8_t  EraseSingleBlockEnable:1;  /* Erase single block enable */
+  uint8_t  EraseSectorSize:7;         /* Erase group size multiplier */
+  uint8_t  WrProtectGrSize:7;         /* Write protect group size */
+  uint8_t  WrProtectGrEnable:1;       /* Write protect group enable */
+  uint8_t  Reserved2:2;               /* Reserved */
+  uint8_t  WrSpeedFact:3;             /* Write speed factor */
+  uint8_t  MaxWrBlockLen:4;           /* Max. write data block length */
+  uint8_t  WriteBlockPartial:1;       /* Partial blocks for write allowed */
+  uint8_t  Reserved3:5;               /* Reserved */
+  uint8_t  FileFormatGrouop:1;        /* File format group */
+  uint8_t  CopyFlag:1;                /* Copy flag (OTP) */
+  uint8_t  PermWrProtect:1;           /* Permanent write protection */
+  uint8_t  TempWrProtect:1;           /* Temporary write protection */
+  uint8_t  FileFormat:2;              /* File Format */
+  uint8_t  Reserved4:2;               /* Reserved */
+  uint8_t  crc:7;                     /* Reserved */
+  uint8_t  Reserved5:1;               /* always 1*/
+
+} SD_CSD;
+
+/**
+  * @brief  Card Identification Data: CID Register
+  */
+typedef struct
+{
+  __IO uint8_t  ManufacturerID;       /* ManufacturerID */
+  __IO uint16_t OEM_AppliID;          /* OEM/Application ID */
+  __IO uint32_t ProdName1;            /* Product Name part1 */
+  __IO uint8_t  ProdName2;            /* Product Name part2*/
+  __IO uint8_t  ProdRev;              /* Product Revision */
+  __IO uint32_t ProdSN;               /* Product Serial Number */
+  __IO uint8_t  Reserved1;            /* Reserved1 */
+  __IO uint16_t ManufactDate;         /* Manufacturing Date */
+  __IO uint8_t  CID_CRC;              /* CID CRC */
+  __IO uint8_t  Reserved2;            /* always 1 */
+} SD_CID;
+
+/**
+  * @brief SD Card information
+  */
+typedef struct
+{
+  SD_CSD Csd;
+  SD_CID Cid;
+  uint64_t CardCapacity;              /*!< Card Capacity */
+  uint32_t LogBlockNbr;               /*!< Specifies the Card logical Capacity in blocks   */
+  uint32_t CardBlockSize;             /*!< Card Block Size */
+  uint32_t LogBlockSize;              /*!< Specifies logical block size in bytes           */
+} SD_CardInfo;
+
+typedef struct
+{
+	SD_CardInfo Info;
+	uint64_t SDHCReadBlockTo;
+	uint64_t SDHCWriteBlockTo;
+	Buffer_Struct DataBuf;
+	HANDLE NotifyTask;						//设置了NotifyTask,则会在大量传输SPI数据时,休眠任务但是仍然能接收Event并在CB中处理
+	CBFuncEx_t TaskCB;
+	uint32_t Size;							//flash的大小KB
+	uint32_t OCR;
+	uint16_t WriteWaitCnt;
+	uint8_t CSPin;
+	uint8_t SpiID;
+	uint8_t IsSpiDMAMode;
+	uint8_t SDHCState;
+	uint8_t IsInitDone;
+	uint8_t SDHCError;
+	uint8_t SPIError;
+	uint8_t ExternResult[8];
+	uint8_t ExternLen;
+	uint8_t TempData[__SDHC_BLOCK_LEN__ + 8];
+	uint8_t IsPrintData;
+	uint8_t IsMMC;
+}SDHC_SPICtrlStruct;
+
+
+
+void SDHC_SpiInitCard(void *pSDHC);
+void SDHC_SpiReadCardInfo(void *pSDHC);
+void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums);
+void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums);
+void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin);
+uint8_t SDHC_IsReady(void *pSDHC);
+uint32_t SDHC_GetLogBlockNbr(void *pSDHC);
+#endif

+ 2 - 13
bsp/device/include/dev_spiflash.h

@@ -1,5 +1,5 @@
-#ifndef __CORE_SPIFLASH_H__
-#define __CORE_SPIFLASH_H__
+#ifndef __DEV_SPIFLASH_H__
+#define __DEV_SPIFLASH_H__
 
 #define SPIFLASH_CMD_WREN		(0x06)	//写使能
 #define SPIFLASH_CMD_WRDI		(0x04)	//写禁止
@@ -82,17 +82,6 @@ typedef struct
 	uint8_t CSPin;
 }SPIFlash_CtrlStruct;
 
-enum
-{
-	SPIFLASH_STATE_IDLE = 0,
-	SPIFLASH_STATE_RUN,
-	SPIFLASH_STATE_READ,
-	SPIFLASH_STATE_ERASE,
-	SPIFLASH_STATE_WRITE,
-};
-
-
-
 
 void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *Config);
 int32_t SPIFlash_ID(SPIFlash_CtrlStruct *Ctrl);

+ 729 - 0
bsp/device/src/dev_sdhc_spi.c

@@ -0,0 +1,729 @@
+#include "user.h"
+#define CMD0	(0)			/* GO_IDLE_STATE */
+#define CMD1	(1)			/* SEND_OP_COND */
+#define CMD2	(2)
+#define	ACMD41	(0x80+41)	/* SEND_OP_COND (SDC) */
+#define CMD8	(8)			/* SEND_IF_COND */
+#define CMD9	(9)			/* SEND_CSD */
+#define CMD10	(10)		/* SEND_CID */
+#define CMD12	(12)		/* STOP_TRANSMISSION */
+#define CMD13	(13)		/* SEND_STATUS */
+#define ACMD13	(0x80+13)	/* SD_STATUS (SDC) */
+#define CMD16	(16)		/* SET_BLOCKLEN */
+#define CMD17	(17)		/* READ_SINGLE_BLOCK */
+#define CMD18	(18)		/* READ_MULTIPLE_BLOCK */
+#define CMD23	(23)		/* SET_BLOCK_COUNT */
+#define	ACMD23	(0x80+23)	/* SET_WR_BLK_ERASE_COUNT (SDC) */
+#define CMD24	(24)		/* WRITE_BLOCK */
+#define CMD25	(25)		/* WRITE_MULTIPLE_BLOCK */
+#define CMD32	(32)		/* ERASE_ER_BLK_START */
+#define CMD33	(33)		/* ERASE_ER_BLK_END */
+#define CMD38	(38)		/* ERASE */
+#define CMD55	(55)		/* APP_CMD */
+#define CMD58	(58)		/* READ_OCR */
+
+#define SD_CMD_GO_IDLE_STATE          0   /* CMD0 = 0x40  */
+#define SD_CMD_SEND_OP_COND           1   /* CMD1 = 0x41  */
+#define SD_CMD_SEND_IF_COND           8   /* CMD8 = 0x48  */
+#define SD_CMD_SEND_CSD               9   /* CMD9 = 0x49  */
+#define SD_CMD_SEND_CID               10  /* CMD10 = 0x4A */
+#define SD_CMD_STOP_TRANSMISSION      12  /* CMD12 = 0x4C */
+#define SD_CMD_SEND_STATUS            13  /* CMD13 = 0x4D */
+#define SD_CMD_SET_BLOCKLEN           16  /* CMD16 = 0x50 */
+#define SD_CMD_READ_SINGLE_BLOCK      17  /* CMD17 = 0x51 */
+#define SD_CMD_READ_MULT_BLOCK        18  /* CMD18 = 0x52 */
+#define SD_CMD_SET_BLOCK_COUNT        23  /* CMD23 = 0x57 */
+#define SD_CMD_WRITE_SINGLE_BLOCK     24  /* CMD24 = 0x58 */
+#define SD_CMD_WRITE_MULT_BLOCK       25  /* CMD25 = 0x59 */
+#define SD_CMD_PROG_CSD               27  /* CMD27 = 0x5B */
+#define SD_CMD_SET_WRITE_PROT         28  /* CMD28 = 0x5C */
+#define SD_CMD_CLR_WRITE_PROT         29  /* CMD29 = 0x5D */
+#define SD_CMD_SEND_WRITE_PROT        30  /* CMD30 = 0x5E */
+#define SD_CMD_SD_ERASE_GRP_START     32  /* CMD32 = 0x60 */
+#define SD_CMD_SD_ERASE_GRP_END       33  /* CMD33 = 0x61 */
+#define SD_CMD_UNTAG_SECTOR           34  /* CMD34 = 0x62 */
+#define SD_CMD_ERASE_GRP_START        35  /* CMD35 = 0x63 */
+#define SD_CMD_ERASE_GRP_END          36  /* CMD36 = 0x64 */
+#define SD_CMD_UNTAG_ERASE_GROUP      37  /* CMD37 = 0x65 */
+#define SD_CMD_ERASE                  38  /* CMD38 = 0x66 */
+#define SD_CMD_SD_APP_OP_COND         41  /* CMD41 = 0x69 */
+#define SD_CMD_APP_CMD                55  /* CMD55 = 0x77 */
+#define SD_CMD_READ_OCR               58  /* CMD55 = 0x79 */
+#define SD_DEFAULT_BLOCK_SIZE (512)
+
+#define SD_DBG	DBG_INFO
+enum
+{
+	DEV_SDCARD_SPI_DONE = SERVICE_EVENT_ID_START + 1,
+	SDCARD_STATE_IDLE = 0,
+	SDCARD_STATE_RUN,
+	SDCARD_STATE_READ,
+	SDCARD_STATE_WRITE,
+};
+
+static void SDHC_SpiCS(SDHC_SPICtrlStruct *Ctrl, uint8_t OnOff)
+{
+	uint8_t Temp[1] = {0xff};
+	GPIO_Output(Ctrl->CSPin, !OnOff);
+	if (!OnOff)
+	{
+		SPI_BlockTransfer(Ctrl->SpiID, Temp, Temp, 1);
+	}
+
+}
+
+static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
+{
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pParam;
+#ifdef __BUILD_OS__
+	if (Ctrl->NotifyTask)
+	{
+		Task_SendEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, 0, 0, 0);
+	}
+#endif
+	return 0;
+}
+
+static uint8_t CRC7(uint8_t * chr, int cnt)
+{
+	int i,a;
+	uint8_t crc,Data;
+	crc=0;
+	for (a=0;a<cnt;a++)
+	{
+	   Data=chr[a];
+	   for (i=0;i<8;i++)
+	   {
+		crc <<= 1;
+
+		if ((Data & 0x80)^(crc & 0x80))
+		crc ^=0x09;
+		Data <<= 1;
+	   }
+	}
+	crc=(crc<<1)|1;
+	return(crc);
+}
+
+static void SDHC_SpiXfer(SDHC_SPICtrlStruct *Ctrl, uint8_t *Buf, uint16_t TxLen)
+{
+#ifdef __BUILD_OS__
+	Task_EventStruct Event;
+#endif
+#ifdef __BUILD_OS__
+	if (Ctrl->NotifyTask && Ctrl->TaskCB)
+	{
+		Ctrl->SPIError = 0;
+		SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
+		SPI_Transfer(Ctrl->SpiID, Buf, Buf, TxLen, Ctrl->IsSpiDMAMode);
+		if (Task_GetEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, &Event, Ctrl->TaskCB, TxLen * CORE_TICK_1US + CORE_TICK_1MS))
+		{
+			Ctrl->SPIError = 1;
+			SPI_TransferStop(Ctrl->SpiID);
+		}
+		SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
+	}
+	else
+#endif
+	{
+		SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, TxLen);
+	}
+}
+
+static int32_t SDHC_SpiCmd(SDHC_SPICtrlStruct *Ctrl, uint8_t Cmd, uint32_t Arg, uint8_t NeedStop)
+{
+	uint64_t OpEndTick;
+	uint8_t i, TxLen, DummyLen;
+	int32_t Result = -ERROR_OPERATION_FAILED;
+	SDHC_SpiCS(Ctrl, 1);
+	Ctrl->TempData[0] = 0x40|Cmd;
+	BytesPutBe32(Ctrl->TempData + 1, Arg);
+	Ctrl->TempData[5] = CRC7(Ctrl->TempData, 5);
+
+	memset(Ctrl->TempData + 6, 0xff, 8);
+	TxLen = 14;
+
+	if (Ctrl->IsPrintData)
+	{
+		DBG_HexPrintf(Ctrl->TempData, TxLen);
+	}
+	Ctrl->SPIError = 0;
+	Ctrl->SDHCError = 0;
+	SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
+	if (Ctrl->IsPrintData)
+	{
+		DBG_HexPrintf(Ctrl->TempData, TxLen);
+	}
+	for(i = 7; i < TxLen; i++)
+	{
+		if (Ctrl->TempData[i] != 0xff)
+		{
+			Ctrl->SDHCState = Ctrl->TempData[i];
+			if ((Ctrl->SDHCState == !Ctrl->IsInitDone) || !Ctrl->SDHCState)
+			{
+				Result = ERROR_NONE;
+			}
+			DummyLen = TxLen - i - 1;
+			memcpy(Ctrl->ExternResult, &Ctrl->TempData[i + 1], DummyLen);
+			Ctrl->ExternLen = DummyLen;
+			break;
+		}
+	}
+	if (NeedStop)
+	{
+		SDHC_SpiCS(Ctrl, 0);
+	}
+	return Result;
+}
+
+static int32_t SDHC_SpiReadRegData(SDHC_SPICtrlStruct *Ctrl, uint8_t *RegDataBuf, uint8_t DataLen)
+{
+	uint64_t OpEndTick;
+	int Result = ERROR_NONE;
+	uint16_t DummyLen;
+	uint16_t i,findResult;
+	Ctrl->SPIError = 0;
+	Ctrl->SDHCError = 0;
+	OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo;
+	findResult = 0;
+	for(i = 0; i < Ctrl->ExternLen; i++)
+	{
+		if (0xfe == Ctrl->ExternResult[i])
+		{
+			DummyLen = Ctrl->ExternLen - i - 1;
+			if (Ctrl->IsPrintData)
+			{
+				DBG_HexPrintf(&Ctrl->ExternResult[i], DummyLen + 1);
+			}
+			memcpy(RegDataBuf, &Ctrl->ExternResult[i + 1], DummyLen);
+			memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
+			SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
+			if (Ctrl->IsPrintData)
+			{
+				DBG_HexPrintf(RegDataBuf + DummyLen, DataLen - DummyLen);
+			}
+			goto SDHC_SPIREADREGDATA_DONE;
+		}
+	}
+	while((GetSysTick() < OpEndTick) && !Ctrl->SDHCError)
+	{
+		memset(Ctrl->TempData, 0xff, 40);
+		SDHC_SpiXfer(Ctrl, Ctrl->TempData, 40);
+		if (Ctrl->IsPrintData)
+		{
+			DBG_HexPrintf(Ctrl->TempData, 40);
+		}
+		for(i = 0; i < 40; i++)
+		{
+			if (0xfe == Ctrl->TempData[i])
+			{
+				DummyLen = 40 - i - 1;
+				if (DummyLen >= DataLen)
+				{
+					memcpy(RegDataBuf, &Ctrl->TempData[i + 1], DataLen);
+					goto SDHC_SPIREADREGDATA_DONE;
+				}
+				else
+				{
+					memcpy(RegDataBuf, &Ctrl->TempData[i + 1], DummyLen);
+					memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
+					SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
+					goto SDHC_SPIREADREGDATA_DONE;
+				}
+			}
+		}
+	}
+	Result = -ERROR_OPERATION_FAILED;
+SDHC_SPIREADREGDATA_DONE:
+	SDHC_SpiCS(Ctrl, 0);
+	return Result;
+}
+
+
+static int32_t SDHC_SpiWriteBlockData(SDHC_SPICtrlStruct *Ctrl)
+{
+	uint64_t OpEndTick;
+	int Result = -ERROR_OPERATION_FAILED;
+	uint16_t TxLen, DoneFlag, waitCnt;
+	uint16_t i, crc16;
+	uint8_t *pBuf;
+	Ctrl->SPIError = 0;
+	Ctrl->SDHCError = 0;
+	OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS;
+	while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
+	{
+		Ctrl->TempData[0] = 0xff;
+		Ctrl->TempData[1] = 0xff;
+		//SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
+		Ctrl->TempData[2] = 0xfc;
+		memcpy(Ctrl->TempData + 3, Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__);
+		crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
+		BytesPutBe16(Ctrl->TempData + 3 + __SDHC_BLOCK_LEN__, crc16);
+		Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] = 0xff;
+		TxLen = 6 + __SDHC_BLOCK_LEN__;
+		SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
+		if ((Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] & 0x1f) != 0x05)
+		{
+			DBG("write data error ! x%02x", Ctrl->TempData[5 + __SDHC_BLOCK_LEN__]);
+			Ctrl->SDHCError = 1;
+			goto SDHC_SPIWRITEBLOCKDATA_DONE;
+		}
+		DoneFlag = 0;
+		waitCnt = 0;
+		while( (GetSysTick() < OpEndTick) && !DoneFlag )
+		{
+			TxLen = Ctrl->WriteWaitCnt?Ctrl->WriteWaitCnt:40;
+			memset(Ctrl->TempData, 0xff, TxLen);
+			SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
+			for(i = 0; i < TxLen; i++)
+			{
+				if (Ctrl->TempData[i] == 0xff)
+				{
+					DoneFlag = 1;
+					if ((i + waitCnt) < sizeof(Ctrl->TempData))
+					{
+						if ((i + waitCnt) != Ctrl->WriteWaitCnt)
+						{
+//							DBG("%u", Ctrl->WriteWaitCnt);
+							Ctrl->WriteWaitCnt = i + waitCnt;
+						}
+					}
+					break;
+				}
+			}
+			waitCnt += TxLen;
+		}
+		if (!DoneFlag)
+		{
+			DBG("write data timeout!");
+			Ctrl->SDHCError = 1;
+			goto SDHC_SPIWRITEBLOCKDATA_DONE;
+		}
+		Ctrl->DataBuf.Pos++;
+		OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS;
+	}
+	Result = ERROR_NONE;
+SDHC_SPIWRITEBLOCKDATA_DONE:
+	Ctrl->TempData[0] = 0xfd;
+	SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 1);
+
+	OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS * Ctrl->DataBuf.MaxLen;
+	DoneFlag = 0;
+	while( (GetSysTick() < OpEndTick) && !DoneFlag )
+	{
+		TxLen = sizeof(Ctrl->TempData);
+		memset(Ctrl->TempData, 0xff, TxLen);
+		SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
+		for(i = 0; i < TxLen; i++)
+		{
+			if (Ctrl->TempData[i] == 0xff)
+			{
+				DoneFlag = 1;
+				break;
+			}
+		}
+	}
+
+	SDHC_SpiCS(Ctrl, 0);
+
+	return Result;
+}
+
+static int32_t SDHC_SpiReadBlockData(SDHC_SPICtrlStruct *Ctrl)
+{
+	uint64_t OpEndTick;
+	int Result = -ERROR_OPERATION_FAILED;
+	uint16_t ReadLen, DummyLen, RemainingLen;
+	uint16_t i, crc16, crc16_check;
+	uint8_t *pBuf;
+	Ctrl->SPIError = 0;
+	Ctrl->SDHCError = 0;
+
+	OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo * CORE_TICK_1MS;
+	while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
+	{
+
+		DummyLen = (__SDHC_BLOCK_LEN__ >> 1);
+		memset(Ctrl->TempData, 0xff, DummyLen);
+//		SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
+		SDHC_SpiXfer(Ctrl, Ctrl->TempData, DummyLen);
+		RemainingLen = 0;
+		for(i = 0; i < DummyLen; i++)
+		{
+			if (Ctrl->TempData[i] == 0xfe)
+			{
+				ReadLen = (DummyLen - i - 1);
+				RemainingLen = __SDHC_BLOCK_LEN__ - ReadLen;
+				if (ReadLen)
+				{
+					memcpy(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, Ctrl->TempData + i + 1, ReadLen);
+				}
+//				SD_DBG("%u,%u", ReadLen, RemainingLen);
+				goto READ_REST_DATA;
+			}
+		}
+		continue;
+READ_REST_DATA:
+		pBuf = Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__ + ReadLen;
+		memset(pBuf, 0xff, RemainingLen);
+		SDHC_SpiXfer(Ctrl, pBuf, RemainingLen);
+		memset(Ctrl->TempData, 0xff, 2);
+		SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 2);
+		crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
+		crc16_check = BytesGetBe16(Ctrl->TempData);
+		if (crc16 != crc16_check)
+		{
+			DBG("crc16 error %04x %04x", crc16, crc16_check);
+			Result = ERROR_NONE;
+			goto SDHC_SPIREADBLOCKDATA_DONE;
+		}
+		Ctrl->DataBuf.Pos++;
+		OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo * CORE_TICK_1MS;
+	}
+	Result = ERROR_NONE;
+
+SDHC_SPIREADBLOCKDATA_DONE:
+	return Result;
+}
+
+void SDHC_SpiInitCard(void *pSDHC)
+{
+	uint8_t i;
+	uint64_t OpEndTick;
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	memset(Ctrl->TempData, 0xff, 20);
+	Ctrl->IsInitDone = 0;
+	Ctrl->SDHCState = 0xff;
+	Ctrl->Info.CardCapacity = 0;
+	Ctrl->WriteWaitCnt = 40;
+	GPIO_Output(Ctrl->CSPin, 0);
+	SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
+	GPIO_Output(Ctrl->CSPin, 1);
+	memset(Ctrl->TempData, 0xff, 20);
+	SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
+	Ctrl->IsMMC = 0;
+	if (SDHC_SpiCmd(Ctrl, CMD0, 0, 1))
+	{
+		goto INIT_DONE;
+	}
+	OpEndTick = GetSysTick() + 100 * CORE_TICK_1MS;
+	if (SDHC_SpiCmd(Ctrl, CMD8, 0x1aa, 1))	//只支持2G以上的SDHC卡
+	{
+		goto INIT_DONE;
+	}
+WAIT_INIT_DONE:
+	if (GetSysTick() >= OpEndTick)
+	{
+		goto INIT_DONE;
+	}
+	if (SDHC_SpiCmd(Ctrl, SD_CMD_APP_CMD, 0, 1))
+	{
+		goto INIT_DONE;
+	}
+	if (SDHC_SpiCmd(Ctrl, SD_CMD_SD_APP_OP_COND, 0x40000000, 1))
+	{
+		goto INIT_DONE;
+	}
+	Ctrl->IsInitDone = !Ctrl->SDHCState;
+	if (!Ctrl->IsInitDone)
+	{
+		goto WAIT_INIT_DONE;
+	}
+	if (SDHC_SpiCmd(Ctrl, CMD58, 0, 1))
+	{
+		goto INIT_DONE;
+	}
+	Ctrl->OCR = BytesGetBe32(Ctrl->ExternResult);
+//	SD_DBG("sdcard init OK OCR:0x%08x!", Ctrl->OCR);
+	return;
+INIT_DONE:
+	if (!Ctrl->IsInitDone)
+	{
+		SD_DBG("sdcard init fail!");
+	}
+	return;
+}
+
+void SDHC_SpiReadCardConfig(void *pSDHC)
+{
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	uint8_t CSD_Tab[18];
+	uint8_t CID_Tab[18];
+	SD_CSD* Csd = &Ctrl->Info.Csd;
+	SD_CID* Cid = &Ctrl->Info.Cid;
+	SD_CardInfo *pCardInfo = &Ctrl->Info;
+	uint64_t Temp;
+	uint8_t flag_SDHC = (Ctrl->OCR & 0x40000000) >> 30;
+
+	if (Ctrl->Info.CardCapacity) return;
+
+	if (SDHC_SpiCmd(Ctrl, CMD9, 0, 0))
+	{
+		goto READ_CONFIG_ERROR;
+	}
+	if (Ctrl->SDHCState)
+	{
+		goto READ_CONFIG_ERROR;
+	}
+	if (SDHC_SpiReadRegData(Ctrl, CSD_Tab, 18))
+	{
+		goto READ_CONFIG_ERROR;
+	}
+    /*************************************************************************
+      CSD header decoding
+    *************************************************************************/
+
+    /* Byte 0 */
+    Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
+    Csd->Reserved1 =  CSD_Tab[0] & 0x3F;
+
+    /* Byte 1 */
+    Csd->TAAC = CSD_Tab[1];
+
+    /* Byte 2 */
+    Csd->NSAC = CSD_Tab[2];
+
+    /* Byte 3 */
+    Csd->MaxBusClkFrec = CSD_Tab[3];
+
+    /* Byte 4/5 */
+    Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4);
+    Csd->RdBlockLen = CSD_Tab[5] & 0x0F;
+
+    /* Byte 6 */
+    Csd->PartBlockRead   = (CSD_Tab[6] & 0x80) >> 7;
+    Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
+    Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
+    Csd->DSRImpl         = (CSD_Tab[6] & 0x10) >> 4;
+
+    /*************************************************************************
+      CSD v1/v2 decoding
+    *************************************************************************/
+
+    if(!flag_SDHC)
+    {
+		Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2);
+
+		Csd->version.v1.DeviceSize =  ((CSD_Tab[6] & 0x03) << 10)
+								  |  (CSD_Tab[7] << 2)
+								  | ((CSD_Tab[8] & 0xC0) >> 6);
+		Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
+		Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
+		Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
+		Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
+		Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1)
+									 |((CSD_Tab[10] & 0x80) >> 7);
+    }
+    else
+    {
+		Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6);
+		Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9];
+		Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8);
+    }
+
+    Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6;
+    Csd->EraseSectorSize   = ((CSD_Tab[10] & 0x3F) << 1)
+                            |((CSD_Tab[11] & 0x80) >> 7);
+    Csd->WrProtectGrSize   = (CSD_Tab[11] & 0x7F);
+    Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
+    Csd->Reserved2         = (CSD_Tab[12] & 0x60) >> 5;
+    Csd->WrSpeedFact       = (CSD_Tab[12] & 0x1C) >> 2;
+    Csd->MaxWrBlockLen     = ((CSD_Tab[12] & 0x03) << 2)
+                            |((CSD_Tab[13] & 0xC0) >> 6);
+    Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5;
+    Csd->Reserved3         = (CSD_Tab[13] & 0x1F);
+    Csd->FileFormatGrouop  = (CSD_Tab[14] & 0x80) >> 7;
+    Csd->CopyFlag          = (CSD_Tab[14] & 0x40) >> 6;
+    Csd->PermWrProtect     = (CSD_Tab[14] & 0x20) >> 5;
+    Csd->TempWrProtect     = (CSD_Tab[14] & 0x10) >> 4;
+    Csd->FileFormat        = (CSD_Tab[14] & 0x0C) >> 2;
+    Csd->Reserved4         = (CSD_Tab[14] & 0x03);
+    Csd->crc               = (CSD_Tab[15] & 0xFE) >> 1;
+    Csd->Reserved5         = (CSD_Tab[15] & 0x01);
+#if 0
+	if (SDHC_SpiCmd(Ctrl, CMD10, 0, 0))
+	{
+		goto READ_CONFIG_ERROR;
+	}
+	if (Ctrl->SDHCState)
+	{
+		goto READ_CONFIG_ERROR;
+	}
+	if (SDHC_SpiReadRegData(Ctrl, CID_Tab, 18))
+	{
+		goto READ_CONFIG_ERROR;
+	}
+    /* Byte 0 */
+    Cid->ManufacturerID = CID_Tab[0];
+
+    /* Byte 1 */
+    Cid->OEM_AppliID = CID_Tab[1] << 8;
+
+    /* Byte 2 */
+    Cid->OEM_AppliID |= CID_Tab[2];
+
+    /* Byte 3 */
+    Cid->ProdName1 = CID_Tab[3] << 24;
+
+    /* Byte 4 */
+    Cid->ProdName1 |= CID_Tab[4] << 16;
+
+    /* Byte 5 */
+    Cid->ProdName1 |= CID_Tab[5] << 8;
+
+    /* Byte 6 */
+    Cid->ProdName1 |= CID_Tab[6];
+
+    /* Byte 7 */
+    Cid->ProdName2 = CID_Tab[7];
+
+    /* Byte 8 */
+    Cid->ProdRev = CID_Tab[8];
+
+    /* Byte 9 */
+    Cid->ProdSN = CID_Tab[9] << 24;
+
+    /* Byte 10 */
+    Cid->ProdSN |= CID_Tab[10] << 16;
+
+    /* Byte 11 */
+    Cid->ProdSN |= CID_Tab[11] << 8;
+
+    /* Byte 12 */
+    Cid->ProdSN |= CID_Tab[12];
+
+    /* Byte 13 */
+    Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
+    Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
+
+    /* Byte 14 */
+    Cid->ManufactDate |= CID_Tab[14];
+
+    /* Byte 15 */
+    Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
+    Cid->Reserved2 = 1;
+#endif
+    if(flag_SDHC)
+    {
+		pCardInfo->LogBlockSize = 512;
+		pCardInfo->CardBlockSize = 512;
+		Temp = 1024 * pCardInfo->LogBlockSize;
+		pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * Temp;
+		pCardInfo->LogBlockNbr = (pCardInfo->Csd.version.v2.DeviceSize + 1) * 1024;
+    }
+    else
+    {
+		pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ;
+		pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2));
+		pCardInfo->LogBlockSize = 512;
+		pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen);
+		pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
+		pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize);
+    }
+//    DBG("卡容量 %lluKB", pCardInfo->CardCapacity/1024);
+	return;
+READ_CONFIG_ERROR:
+	Ctrl->IsInitDone = 0;
+	Ctrl->SDHCError = 1;
+	return;
+}
+
+void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
+{
+	uint8_t Retry = 0;
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
+SDHC_SPIREADBLOCKS_START:
+	if (SDHC_SpiCmd(Ctrl, CMD18, StartLBA + Ctrl->DataBuf.Pos, 0))
+	{
+		goto SDHC_SPIREADBLOCKS_ERROR;
+	}
+	if (SDHC_SpiReadBlockData(Ctrl))
+	{
+		goto SDHC_SPIREADBLOCKS_ERROR;
+	}
+	if (SDHC_SpiCmd(Ctrl, CMD12, 0, 1))
+	{
+		goto SDHC_SPIREADBLOCKS_ERROR;
+	}
+	if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
+	{
+		Retry++;
+		DBG("%d", Retry);
+		if (Retry > 3)
+		{
+
+			Ctrl->SDHCError = 1;
+			goto SDHC_SPIREADBLOCKS_ERROR;
+		}
+		goto SDHC_SPIREADBLOCKS_START;
+	}
+	return;
+SDHC_SPIREADBLOCKS_ERROR:
+	DBG("!");
+	Ctrl->IsInitDone = 0;
+	Ctrl->SDHCError = 1;
+	return;
+}
+
+void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
+{
+	uint8_t Retry = 0;
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
+SDHC_SPIREADBLOCKS_START:
+	if (SDHC_SpiCmd(Ctrl, CMD25, StartLBA + Ctrl->DataBuf.Pos, 0))
+	{
+		goto SDHC_SPIREADBLOCKS_ERROR;
+	}
+	if (SDHC_SpiWriteBlockData(Ctrl))
+	{
+		goto SDHC_SPIREADBLOCKS_ERROR;
+	}
+	if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
+	{
+		Retry++;
+		if (Retry > 3)
+		{
+			Ctrl->SDHCError = 1;
+			goto SDHC_SPIREADBLOCKS_ERROR;
+		}
+		goto SDHC_SPIREADBLOCKS_START;
+	}
+	return;
+SDHC_SPIREADBLOCKS_ERROR:
+	Ctrl->IsInitDone = 0;
+	Ctrl->SDHCError = 1;
+	return;
+}
+
+void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin)
+{
+	SDHC_SPICtrlStruct *Ctrl = zalloc(sizeof(SDHC_SPICtrlStruct));
+	Ctrl->CSPin = CSPin;
+	Ctrl->SpiID = SpiID;
+	Ctrl->SDHCReadBlockTo = 5 * CORE_TICK_1MS;
+	Ctrl->SDHCWriteBlockTo = 25 * CORE_TICK_1MS;
+//	Ctrl->IsPrintData = 1;
+	return Ctrl;
+}
+
+uint32_t SDHC_GetLogBlockNbr(void *pSDHC)
+{
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	return Ctrl->Info.LogBlockNbr;
+}
+
+uint8_t SDHC_IsReady(void *pSDHC)
+{
+	SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
+	if (!Ctrl->SDHCState && Ctrl->IsInitDone)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+

+ 14 - 6
bsp/device/src/dev_spiflash.c

@@ -1,13 +1,20 @@
 #ifdef __BUILD_OS__
 #include "app_inc.h"
-enum
-{
-	DEV_SPIFLASH_SPI_DONE = SERVICE_EVENT_ID_START + 1,
-};
+
+
 #else
 #include "bl_inc.h"
 #endif
 
+enum
+{
+	SPIFLASH_STATE_IDLE = 0,
+	SPIFLASH_STATE_RUN,
+	SPIFLASH_STATE_READ,
+	SPIFLASH_STATE_ERASE,
+	SPIFLASH_STATE_WRITE,
+};
+
 const uint8_t SPI_FLASH_VENDOR_DICT[] = {
 	0xA1,//"FM"
 	0xC8,//"GD"
@@ -64,7 +71,7 @@ static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
 	SPIFlash_CtrlStruct *Ctrl = (SPIFlash_CtrlStruct *)pParam;
 	SPIFlash_CS(Ctrl, 0);
 #ifdef __BUILD_OS__
-	if (Ctrl->NotifyTask && Ctrl->NotifyTask && Ctrl->IsBlockMode)
+	if (Ctrl->NotifyTask && Ctrl->IsBlockMode)
 	{
 		Task_SendEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, 0, 0, 0);
 	}
@@ -381,7 +388,6 @@ uint8_t SPIFlash_WaitOpDone(SPIFlash_CtrlStruct *Ctrl)
 		return 1;
 	}
 	return 0;
-
 }
 
 int32_t SPIFlash_WriteEnable(SPIFlash_CtrlStruct *Ctrl)
@@ -430,6 +436,7 @@ int32_t SPIFlash_Read(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint8_t *Buf,
 				Ctrl->SPIError = 1;
 				SPI_TransferStop(Ctrl->SpiID);
 			}
+			SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
 			SPIFlash_CS(Ctrl, 0);
 		}
 		else
@@ -493,6 +500,7 @@ int32_t SPIFlash_Write(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, const uint8_
 					Ctrl->SPIError = 1;
 					SPI_TransferStop(Ctrl->SpiID);
 				}
+				SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
 				SPIFlash_CS(Ctrl, 0);
 			}
 			else

BIN
project/air105/soc_download.exe