사용 MCU : STM32F103Zx
사용한 MassStorage 타입 : SD, NandFlash, InterFlash
mass_mal.c에서 수정
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_sdio_sd.h"
#include "usr_nand.h"
#include "mass_mal.h"
#include "usr_led.h"
#include "usr_uart.h"
//#define MASSPRINT DEBUGPRINT
#define MASSPRINT(...)
typedef enum _MASS_ID
{
MASS_SD = 0,
MASS_NAND = 1,
MASS_INTERNNAL = 2,
}MASS_ID_E;
#define MAL_OK 0
#define MAL_FAIL 1
#define MAX_LUN 0 /* 0 SD, 1 SD, NAND Flash, 2 SD, NAND Flash, Internal Flash */
#define FLASH_DISK_START_ADDRESS 0x08050000 /* Flash start address (10K for this bootloader) 0x08002800 -> 0x08060000 */
#define FLASH_DISK_SIZE 0x20000 // 55296 -> 0xA000
#define FLASH_PAGE_SIZE 0x800 /* 1k -> 2K per page */
#define WAIT_TIMEOUT 100000
uint32_t Mass_Memory_Size[3];
uint32_t Mass_Block_Size[3];
uint32_t Mass_Block_Count[3];
uint32_t Max_Lun = MAX_LUN;
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
uint16_t MAL_Init(uint8_t lun)
{
uint16_t status = MAL_OK;
switch (lun)
{
case MASS_SD:
status = SD_Init();
if (status != SD_OK){
MASSPRINT("SD_Init() fail (%d) : file %s on line %d\r\n", status, __FILE__, __LINE__);
status = MAL_FAIL;
}
else{
MASSPRINT("SD_Init() Ok\r\n");
status = MAL_OK;
}
break;
case MASS_NAND:
if (NAND_Init() != NAND_OK){
MASSPRINT("NAND_Init() fail : file %s on line %d\r\n", __FILE__, __LINE__);
status = MAL_FAIL;
}
else{
MASSPRINT("NAND_Init() Ok\r\n");
status = MAL_OK;
}
break;
case MASS_INTERNNAL:
FLASH_Unlock();
break;
default:
break;
}
return status;
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
{
uint16_t status = MAL_OK;
uint16_t i;
switch (lun)
{
case MASS_SD:
status = SD_WriteBlock((uint8_t*)Writebuff, Memory_Offset, Transfer_Length);
if (status != SD_OK)
{
MASSPRINT("SD_WriteBlock(, 0x%X, 0x%X) Fail(%d) \r\n", Memory_Offset, Transfer_Length, status);
status = MAL_FAIL;
}
else
{
MASSPRINT("SD_WriteBlock(, 0x%X, 0x%X) Ok\r\n", Memory_Offset, Transfer_Length);
status = MAL_OK;
}
break;
case MASS_NAND:
if (NAND_Write(Memory_Offset, Writebuff, Transfer_Length) != NAND_OK)
{
MASSPRINT("NAND_Write(0x%X, ,0x%X) Fail\r\n", Memory_Offset, Transfer_Length);
status = MAL_FAIL;
}
else
{
MASSPRINT("NAND_Write(0x%X, ,0x%X) Ok\r\n", Memory_Offset, Transfer_Length);
status = MAL_OK;
}
break;
case MASS_INTERNNAL:
for(i = 0; i < Transfer_Length; i += FLASH_PAGE_SIZE)
{
if (FLASH_WaitForLastOperation(WAIT_TIMEOUT) != FLASH_TIMEOUT)
{
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
}
FLASH_ErasePage(FLASH_DISK_START_ADDRESS + Memory_Offset + i);
}
for(i = 0; i < Transfer_Length; i += 4)
{
if(FLASH_WaitForLastOperation(WAIT_TIMEOUT) != FLASH_TIMEOUT)
{
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
}
FLASH_ProgramWord(FLASH_DISK_START_ADDRESS + Memory_Offset + i , Writebuff[i >> 2]);
}
break;
default:
break;
}
return status;
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
{
uint16_t status = MAL_OK;
uint16_t i;
switch (lun)
{
case MASS_SD:
status = SD_ReadBlock((uint8_t*)Readbuff, Memory_Offset, Transfer_Length);
if (status != SD_OK)
{
MASSPRINT("SD_ReadBlock(, 0x%X, 0x%X) Fail(%d) \r\n", Memory_Offset, Transfer_Length, status);
status = MAL_FAIL;
}
else
{
MASSPRINT("SD_ReadBlock(, 0x%X, 0x%X) Ok\r\n", Memory_Offset, Transfer_Length);
status = MAL_OK;
}
break;
case MASS_NAND:
if (NAND_Read(Memory_Offset, Readbuff, Transfer_Length) != NAND_OK)
{
MASSPRINT("NAND_Read(0x%X, ,0x%X) Fail\r\n", Memory_Offset, Transfer_Length);
status = MAL_FAIL;
}
else
{
MASSPRINT("NAND_Read(0x%X, ,0x%X) Ok\r\n", Memory_Offset, Transfer_Length);
status = MAL_OK;
}
break;
case MASS_INTERNNAL:
for(i = 0; i < Transfer_Length; i += 4)
{
Readbuff[i >> 2] = ((vu32*)(FLASH_DISK_START_ADDRESS + Memory_Offset))[i >> 2];
}
break;
default:
break;
}
return status;
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
uint16_t MAL_GetStatus (uint8_t lun)
{
SD_CardInfo mSDCardInfo;
uint32_t DeviceSizeMul = 0, NumberOfBlocks = 0;
uint32_t nand_id;
uint16_t status = MAL_OK;
switch (lun)
{
case MASS_SD:
{
status = SD_Init();
if (status != SD_OK)
{
MASSPRINT("SD_Init() fail (%d) : file %s on line %d\r\n", status, __FILE__, __LINE__);
status = MAL_FAIL;
break;
}
SD_GetCardInfo(&mSDCardInfo);
SD_SelectDeselect((uint32_t) (mSDCardInfo.RCA << 16));
DeviceSizeMul = (mSDCardInfo.SD_csd.DeviceSizeMul + 2);
if (mSDCardInfo.CardType == SDIO_HIGH_CAPACITY_SD_CARD){
Mass_Block_Count[MASS_SD] = (mSDCardInfo.SD_csd.DeviceSize + 1) * 1024;
MASSPRINT("SD_GetCardInfo() Ok, SDHC Card\r\n");
}
else{
NumberOfBlocks = ((1 << (mSDCardInfo.SD_csd.RdBlockLen)) / 512);
Mass_Block_Count[MASS_SD] = ((mSDCardInfo.SD_csd.DeviceSize + 1) * (1 << DeviceSizeMul) << (NumberOfBlocks/2));
MASSPRINT("SD_GetCardInfo() Ok, Normal SD Card\r\n");
}
Mass_Block_Size[MASS_SD] = 512;
status = SD_SelectDeselect((uint32_t) (mSDCardInfo.RCA << 16));
status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
if (status != SD_OK){
MASSPRINT("SD_EnableWideBusOperation(SDIO_BusWide_4b) Fail (%d)\r\n", status);
status = MAL_FAIL;
break;
}
status = SD_SetDeviceMode(SD_DMA_MODE);
if (status != SD_OK){
MASSPRINT("SD_SetDeviceMode(SD_DMA_MODE) Fail (%d)\r\n", status);
status = MAL_FAIL;
break;
}
Mass_Memory_Size[MASS_SD] = Mass_Block_Count[MASS_SD] * Mass_Block_Size[MASS_SD];
OUTPUT_On(OUTPUTPIN_2);
MASSPRINT("MAL_GetStatus(MASS_SD) Ok. Memory Size = %uMB\r\n", Mass_Memory_Size[0]/(1024*1024));
status = MAL_OK;
break;
}
case MASS_NAND:
{
nand_id = NAND_ReadID();
if ((nand_id != 0)
{
Mass_Block_Count[MASS_NAND] = NAND_ZONE_SIZE * NAND_BLOCK_SIZE * NAND_MAX_ZONE;
Mass_Block_Size[MASS_NAND] = NAND_PAGE_SIZE;
Mass_Memory_Size[MASS_NAND] = (Mass_Block_Count[MASS_NAND] * Mass_Block_Size[MASS_NAND]);
OUTPUT_On(OUTPUTPIN_2);
MASSPRINT("MAL_GetStatus(MASS_NAND) Ok. Memory Size = %uMB\r\n", Mass_Memory_Size[MASS_NAND]/(1024*1024));
status = MAL_OK;
}
else
{
MASSPRINT("MAL_GetStatus(MASS_NAND) Fail\r\n");
status = MAL_FAIL;
}
break;
}
case MASS_INTERNNAL:
{
Mass_Block_Count[MASS_INTERNNAL] = FLASH_DISK_SIZE / FLASH_PAGE_SIZE;
Mass_Block_Size[MASS_INTERNNAL] = FLASH_PAGE_SIZE;
Mass_Memory_Size[MASS_INTERNNAL] = FLASH_DISK_SIZE;
break;
}
default:
status = MAL_FAIL;
break;
}
return status;
}
'초보의 아웅다웅 설계하기 > STM32' 카테고리의 다른 글
LCD 5*8 픽셀 글자 (0) | 2018.07.27 |
---|---|
Tamper 사용 (0) | 2018.07.23 |
USB Composite (0) | 2018.07.22 |
error C1189: #error : MFC does not support WINVER less than 0x0501. (0) | 2018.07.18 |
Buzzer Melody (0) | 2018.07.16 |