STM32F1 Mass storage + внутренняя FLASH

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
AlexZavgorodniy
Родился
Сообщения: 10
Зарегистрирован: Пн июн 25, 2012 05:02:00

STM32F1 Mass storage + внутренняя FLASH

Сообщение AlexZavgorodniy »

Всем доброго дня!

Товарищи, прошу вашей помощи. Пытаюсь сделать устройство Mass Storage с использованием внутренней памяти. ПК видит устройство и его объем (100кБ в моем случае). Но вот форматирование проходит неудачно.

мк STM32F103RC

дефайны следующие

#define FLASH_MSD_START_ADDR 0x08027000

#define STORAGE_LUN_NBR 1
#define STORAGE_BLK_NBR 0xC8
#define STORAGE_BLK_SIZ 0x200

функция чтения

Код: Выделить всё

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
  uint32_t i;
  switch (lun)
  {
    case 0:
       for(i = 0; i < blk_len*STORAGE_BLK_SIZ; i += 4)
         {
             *(uint32_t*)(&buf[i]) = ((volatile uint32_t*)(FLASH_MSD_START_ADDR + blk_addr*STORAGE_BLK_SIZ))[i];
         }
      break;
    case 1:
      break;
    default:
      return USBD_FAIL;
  }
   
  return (USBD_OK);
  /* USER CODE END 6 */
}
запись

Код: Выделить всё

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */

   FLASH_EraseInitTypeDef EraseInitStruct;
   uint32_t PAGEError = 0;
  uint32_t i;
  switch (lun)
  {
    case 0:   
      for(i = 0; i < blk_len*STORAGE_BLK_SIZ; i += FLASH_PAGE_SIZE)
      {
            EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
            EraseInitStruct.PageAddress = FLASH_MSD_START_ADDR + blk_addr*STORAGE_BLK_SIZ + i;
            EraseInitStruct.NbPages     = 1;
            if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
            {   
               // error
            }
      }         
      
      for(i = 0; i < blk_len*STORAGE_BLK_SIZ; i += 4)
      {
          HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,FLASH_MSD_START_ADDR + blk_addr*STORAGE_BLK_SIZ + i , *(uint32_t*)(&buf[i]));
      }
      
      break;
    case 1:
      break;
    default:
      return USBD_FAIL;
  }
  return (USBD_OK);
  /* USER CODE END 7 */
}
При попытке форматирования в память МК ложиться всякая фигня.

Спасибо!!!
Реклама
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: STM32F1 Mass storage + внутренняя FLASH

Сообщение arkhnchul »

а флеш внуьренний разблокировали где-нибудь?
Реклама
AlexZavgorodniy
Родился
Сообщения: 10
Зарегистрирован: Пн июн 25, 2012 05:02:00

Re: STM32F1 Mass storage + внутренняя FLASH

Сообщение AlexZavgorodniy »

Нашел проект на гитхабе
https://github.com/wegi1/STM32F107VCT6_AS_PENDRIVE

в настройках куба нужно было изменить MSC_MEDIA_PACKET на 2048

и в коде указать

Код: Выделить всё

#define STORAGE_BLK_NBR                  50
#define STORAGE_BLK_SIZ                  2048
также взял оттуда функции чтения/записи

Код: Выделить всё


int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
   memcpy(buf, (void *)(STORAGE_ADDRESS + STORAGE_BLK_SIZ * blk_addr), (STORAGE_BLK_SIZ * blk_len));

   return (USBD_OK);
}



int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
   /* USER CODE BEGIN 7 */

    ERASE_One_Page((STORAGE_ADDRESS) + (STORAGE_BLK_SIZ * blk_addr));

    WRITE_One_Page(((uint64_t *)buf), ((STORAGE_ADDRESS)+(STORAGE_BLK_SIZ * blk_addr)));

   return (USBD_OK);
   /* USER CODE END 7 */
}


void WRITE_One_Page(uint64_t *bufptr, uint32_t page_address)
{
   for(uint32_t i = 0; i < STORAGE_BLK_SIZ ; i += 8)
   {
      HAL_FLASH_Program(FLASH_PROC_PROGRAMDOUBLEWORD , (page_address + i) , *bufptr); //send 8 bytes to write
      bufptr ++; // bufptr is 64bit value - incrementation onward 8 bytes
   }
}



void ERASE_One_Page(uint32_t page_address)
{
   FLASH_EraseInitTypeDef flashErase_handle; // declare structure to erase page
   uint32_t sectorError; // if check any errors after erase here you can...

   //memset(&flashErase_handle, 0, sizeof(flashErase_handle)); // don't need every one field this structure is initialize here
   HAL_FLASH_Unlock(); //don't need it's on time unlocked in STORAGE_FileSystem_Init function

   flashErase_handle.TypeErase = FLASH_TYPEERASE_PAGES; // page type erase
   flashErase_handle.Banks = FLASH_BANK_1; //bank 1
   flashErase_handle.PageAddress = page_address; // address of page to erase
   flashErase_handle.NbPages = 1 ; // only one page to erase

   HAL_FLASHEx_Erase(&flashErase_handle, &sectorError); // Let's do ERASE ONE PAGE...

   //HAL_FLASH_Lock();
}
теперь все работает. Винда видит флешку, форматирует успешно.
Ответить

Вернуться в «ARM»