📄 sddriver.c
字号:
ret = SD_JudgeResult(tmp); /* 响应指示写失败 response indicate write fail */ if (ret != SD_NO_ERR) return ret; } ret = SD_ReadCard_Status(sds->RCA, 4, tmp); if (ret != SD_NO_ERR) return ret; ret = SD_DeSelectCard(); /* CMD7, 退出传输状态 */ return ret; /* 返回写入结果 return the result of writing */ }/********************************************************************************************************************* 函数名称: INT8U SD_GetCardInfo() Name: INT8U SD_GetCardInfo()** 功能描述: 获得SD卡的信息 Function: get the information of SD card** 输 入: sd_struct *sds: SD卡信息结构体 Input: sd_struct *sds: the information structure of SD Card** 输 出: 0: 成功 > 0: 错误码 Output: 0: sucessfully > 0: error code*******************************************************************************************************************/INT8U SD_GetCardInfo(sd_struct *sds){ INT32U tmp; INT8U time_u,time_v,fator; INT8U recbuf[16],ret; ret = SD_ReadCSD(sds->RCA, 16, recbuf); /* 读CSD寄存器 read CSD register */ if (ret != SD_NO_ERR) return ret; /* 计算块的最大长度 calculate the size of a sector */ sds->block_len = 1 << (recbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK); /* (2 ^ READ_BL_LEN) */ /* 计算卡中块的个数 calculate the sector numbers of the SD Card */ sds->block_num = ((recbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) + (recbuf[C_SIZE_POS2] << 2) + ((recbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1; /* 计算(C_SIZE + 1)*/ tmp = ((recbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) + ((recbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2; /* 计算(C_SIZE_MULT + 2) */ sds->block_num = sds->block_num * (1 << tmp); /* 获得卡中块的数量: (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */ /* get the block numbers in card: (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */ /* 计算扇区大小 calculate the size of sector */ tmp = ((recbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) + ((recbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* 计算(SECTOR_SIZE + 1)*/ sds->sector_size = tmp; /* 保存在sds中 save into sds */ return SD_NO_ERR; /* 返回执行成功 return perform sucessfully */}/*********************************************************************************************************** Function name: Card_Indentify** Descriptions: identify card type: SD or MMC card** 判别卡的型号:SD或MMC卡 ** Input: sd_struct *sds : SD/MMC卡信息结构体 sd_struct *sds : the information structure of SD/MMC ** Output: CARDTYPE_SD -- SD card CARDTYPE_MMC -- MMC card ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U Card_Indentify(void){ INT32U param = 0; INT8U response[6],ret; ret = SD_SendCommand(CMD55, param, CMD55_R, response); if (ret == SD_NO_ERR) return CARDTYPE_SD; else return CARDTYPE_MMC;} /*********************************************************************************************************** Function name: SD_ActiveCard** Descriptions: active card** 激活卡 ** Input: NULL** Output: 0: 成功 > 0: 错误码 0: sucessfully > 0: error code ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_ActiveCard(sd_struct *sds){ INT8U ret,resp[4]; INT32U count = 0; do { if (sds->card_type == CARDTYPE_SD) /* 读OCR寄存器 read OCR register */ ret = SD_ReadOCR(4, resp); else ret = MMC_ReadOCR(4, resp); if (ret != SD_NO_ERR) return ret; if (count >= SD_IDLE_WAIT_MAX) return SD_ERR_TIMEOUT_WAITIDLE; /* 超时,返回错误码 timeout,return error code */ count ++; }while ((resp[3] & MSK_READY) == 0x00); if ((resp[2] & MSK_OCR_33) != MSK_OCR_33) return SD_ERR_VOL_NOTSUSP; /* 卡不支3.3V电压 card don't support 3.3V voltage */ return SD_NO_ERR;}/*********************************************************************************************************** Function name: sdmmc_interrupt** Descriptions: SD/MMC card interrupt handler ** SD/MMC 卡中断处理程序 ** Input: input parameter of linux interrupt handler** Output: NULL ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/#if SD_INTERRUPT_ENvoid sdmmc_interrupt(int irq, void *dev_id, struct pt_regs *regs){ INT32U stat; INT32U cnt; INT32U tmp; if (reading == 1) { stat = SDIFSTA; /* 读FIFO状态寄存器 */ /* FIFO 中的数据不足64个字节 */ if (stat & SDIFSTA_RX_LAST) { /* 最后数据就绪 */ cnt = (stat & SDIFSTA_CNT) / sizeof(INT32U); /* 取得FIFO中的“字”数 */ while (cnt) { tmp = SDIDAT; /* 从FIFO中读出数据 */ buffer[bufcnt] = (INT8U)(tmp); buffer[bufcnt + 1] = (INT8U)(tmp >> 8); buffer[bufcnt + 2] = (INT8U)(tmp >> 16); buffer[bufcnt + 3] = (INT8U)(tmp >> 24); bufcnt += sizeof(INT32U); cnt--; } /* Rx FIFO为满,那么读64个字节 */ } else if (stat & SDIFSTA_RX_FULL) { cnt = SDI_MAX_RX_FIFO / sizeof(INT32U); while (cnt && bufcnt < datalen) { tmp = SDIDAT; /* 从FIFO中读出数据 */ buffer[bufcnt] = (INT8U)(tmp); buffer[bufcnt + 1] = (INT8U)(tmp >> 8); buffer[bufcnt + 2] = (INT8U)(tmp >> 16); buffer[bufcnt + 3] = (INT8U)(tmp >> 24); bufcnt += sizeof(INT32U); cnt--; } } stat = SDIDSTA; if (stat & SDIDSTA_DFIN) { /* 数据传输完成 */ SDIDSTA = stat; error = SD_NO_ERR; wake_up_interruptible(&wq); } else if (stat & SDIDSTA_TOUT) { /* 数据/忙接收超时 */ SDIDSTA = stat; error = SD_ERR_TIMEOUT_READ; wake_up_interruptible(&wq); } } /* 下面为写状态 */ else { stat = SDIFSTA; if (stat & SDIFSTA_TX_EMP) { /* TX FIFO 为空 */ cnt = SDI_MAX_TX_FIFO / sizeof(INT32U); while (cnt && bufcnt < datalen) { /* 往FIFO里写入数据 */ SDIDAT = (buffer[bufcnt + 3] << 24) + (buffer[bufcnt + 2] << 16) + (buffer[bufcnt + 1] << 8) + buffer[bufcnt]; bufcnt += sizeof(INT32U); cnt--; } } stat = SDIDSTA; if (stat & SDIDSTA_DFIN) { /* 数据传输完成,使能等待任务 */ SDIDSTA = stat; error = SD_NO_ERR; wake_up_interruptible(&wq); } else if (stat & SDIDSTA_TOUT) { /* 数据传输超时 */ SDIDSTA = stat; error = SD_ERR_TIMEOUT_WRITE; wake_up_interruptible(&wq); } } /* clear the interrupt of mcu */ SRCPND = 1 << 21; /* 清除相关中断标志 */ INTPND = 1 << 21; }#endif/*********************************************************************************************************** Function name: card_detect_interrupt** Descriptions: the interrupt handler of card insert detect** 卡插入检测中断处理函数 ** Input: input parameter of linux interrupt handler** Output: NULL ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/void card_detect_interrupt(int irq, void *dev_id, struct pt_regs *regs){ int bempty;#ifdef SD_CD_LEVEL_LOW /* 如果是低电平表示插入 */ bempty = read_gpio_bit(SD_GPIO_CD);#else bempty = !read_gpio_bit(SD_GPIO_CD);#endif if ((!card_insert) && (!bempty)) { /* card inserted 卡插入 */ card_insert = 1; card_change = 1; printk("SD/MMC card insert!\n"); } else if (card_insert && bempty) { /* card ejected 卡拔出 */ card_insert = 0; card_change = 1;#if SD_INTERRUPT_EN error = SD_ERR_NO_CARD; /* no card error code */ wake_up_interruptible(&wq);#endif printk("SD/MMC card ejected!\n"); } }/*********************************************************************************************************** End Of File**********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -