초보의 아웅다웅 설계하기/STM32

다중 이동식 저장장치

로망와니 2018. 7. 23. 09:40

사용 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