K1Guitar/AT32F403ARCT7_BOOT/project/src/msc_diskio.c

378 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
**************************************************************************
* @file msc_diskio.c
* @version v2.1.1
* @date 2022-07-22
* @brief usb mass storage disk function
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include <string.h>
#include "msc_diskio.h"
#include "msc_bot_scsi.h"
#include "W25Q128.h"
#define MountDisk 0
//==============================================================================
//
//==============================================================================
void flash_read(uint32_t read_addr, uint8_t *p_buffer, uint16_t num_read)
{
uint16_t i;
for(i = 0; i < num_read; i++)
{
p_buffer[i] = *(uint8_t*)(read_addr);
read_addr += 1;
}
}
uint8_t flash_write(uint32_t write_addr, uint8_t *p_buffer, uint16_t num_Write)
{
uint32_t idx = 0;
flash_status_type status = FLASH_OPERATE_DONE;
flash_unlock();
status = flash_sector_erase(write_addr ); // 2K Erase
if(status != FLASH_OPERATE_DONE)
return 0;
status = flash_sector_erase(write_addr + 0x800); // 2K Erase
if(status != FLASH_OPERATE_DONE)
return 0;
for(idx = 0; idx < num_Write; idx += 4)
{
status = flash_word_program((uint32_t)(write_addr + idx), *((uint32_t *)(p_buffer+idx)));
if(status != FLASH_OPERATE_DONE)
return 0;
}
flash_lock();
return 1;
}
//==============================================================================
/** @addtogroup AT32F415_periph_examples
* @{
*/
char strSignature[] = "RYAN";
iap_struct_type* pIAP;
iap_struct_type IAP = {0,};
iap_info_struct_type DL_Info = {{'R','Y','A','N'},0,};
iap_state_machine IAP_CURR_STATE = IAP_STATE_IDEL;
/** @addtogroup 415_USB_device_msc
* @{
*/
uint32_t sector_size = 2048;
uint32_t msc_flash_size;
uint8_t scsi_inquiry[MSC_SUPPORT_MAX_LUN][SCSI_INQUIRY_DATA_LENGTH] =
{
/* lun = 0 */
{
0x00, /* peripheral device type (direct-access device) */
0x80, /* removable media bit */
0x00, /* ansi version, ecma version, iso version */
0x00, /* respond data format */
SCSI_INQUIRY_DATA_LENGTH - 5, /* additional length */
0x00, 0x00, 0x00, /* reserved */
'D', '.', 'R', 'y', 'a', 'n', ' ', ' ', /* vendor information "AT32" */
'I', 'A', 'P', ' ', 'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ', ' ', ' ', ' ', ' ', /* Product identification "Disk" */
'1', '.', '0', '0' /* product revision level */
}
};
/**
* @brief get disk inquiry
* @param lun: logical units number
* @retval inquiry string
*/
uint8_t *get_inquiry(uint8_t lun)
{
if(lun < MSC_SUPPORT_MAX_LUN)
return (uint8_t *)scsi_inquiry[lun];
else
return NULL;
}
/**
* @brief disk read
* @param lun: logical units number
* @param addr: logical address
* @param read_buf: pointer to read buffer
* @param len: read length
* @retval status of usb_sts_type
*/
int8_t msc_disk_read(uint8_t lun, uint32_t addr, uint8_t *read_buf, uint32_t len)
{
uint8_t *Address;
uint8_t buff[32];
switch(lun)
{
case 0:
#if MountDisk
flash_spi_read(read_buf,addr,len);
#else
if(addr == 0x00000000)
{
switch(IAP.cmd[0])
{
case UFI_MODE_GET_VERSION:
Address = (uint8_t*)0x08008400;
memcpy(buff,Address,32);
if( strcmp((const char *)buff,"SLL_SR80\x00")!= 0)
{
memcpy((void *)&buff[0],"SLL_SR80\x00",9);
memcpy((void *)&buff[16],"None\x00",5);
}
memcpy(read_buf,buff,32);
IAP.cmd[0] = UFI_MODE_NORMAL;
break;
case UFI_MODE_NORMAL:
default:
memset(read_buf,0xFF,len);
break;
}
}
else if((addr >= 0x00108000)&&(addr < 0x00140000))
{
if(IAP_CURR_STATE == IAP_STATE_VERIFY_PACKET)
{
flash_read(addr-0x00100000,read_buf,len);
}
else
memset(read_buf,0xFF,len);
}
else if(addr >= 0x01000000)
{
if(IAP_CURR_STATE == IAP_STATE_VERIFY_PACKET)
{
// flash_spi_read(read_buf,addr-0x01000000,len);
W25Q128_Read(read_buf,addr-0x01000000,len);
}
else
memset(read_buf,0xFF,len);
}
else
memset(read_buf,0xFF,len);
#endif
break;
case 1:
break;
}
return USB_OK;
}
/**
* @brief disk write
* @param lun: logical units number
* @param addr: logical address
* @param buf: pointer to write buffer
* @param len: write length
* @retval status of usb_sts_type
*/
int8_t msc_disk_write(uint8_t lun, uint32_t addr, uint8_t *buf, uint32_t len)
{
// char str[20] = {0};
// uint8_t Percentage;
uint16_t FileType;
switch(lun)
{
case 0:
#if MountDisk
// flash_spi_write(buf,addr,len);
W25Q128_WriteSector_4K(buf,addr,len);
#else
if(addr == 0x00000000)
{
pIAP = (iap_struct_type*)buf;
if(strcmp((const char*)pIAP->header,strSignature) == 0x00)
{
memcpy(IAP.header,buf,8);
switch(IAP.cmd[0])
{
case UFI_MODE_SET_INFO:
//LCD_Text(0,48,"CID: ",true,TFT_WHITE, TFT_BLACK,0xFF);
pIAP->pdata[12] = 0;
//LCD_Text(60,48,(const char*)pIAP->pdata,true,TFT_WHITE, TFT_BLACK,0xFF);
break;
case UFI_MODE_DOWN_INFO:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 iFlash, 2 eFlash
//LCD_Fill(0,72,TFT_WIDTH,TFT_HEIGHT,TFT_BLACK);//<2F><><EFBFBD><EFBFBD>
FileType = *(uint16_t*)&pIAP->pdata[0];
if(FileType == 1)
{
// LCD_Text(0,72,"FW Upgrade ",true,TFT_WHITE, TFT_BLACK,0xFF);
// // Size
// DL_Info.iFileSize = *(uint32_t*)&pIAP->pdata[4];
// sprintf(str,"Size : %dK", DL_Info.iFileSize/1024);
// LCD_Text(0,96,str,true,TFT_WHITE, TFT_BLACK,0xFF);
// // CRC
// DL_Info.iFileCRC = *(uint16_t*)&pIAP->pdata[2];
// sprintf(str,"CRC : 0x%04X", DL_Info.iFileCRC);
// LCD_Text(0,120,str,true,TFT_WHITE, TFT_BLACK,0xFF);
// // PCnt
// DL_Info.iFilePacket = *(uint32_t*)&pIAP->pdata[8];
}
if(FileType == 2)
{
// LCD_Text(0,72,"RES Upgrade ",true,TFT_WHITE, TFT_BLACK,0xFF);
// // Size
// DL_Info.eFileSize = *(uint32_t*)&pIAP->pdata[4];
// sprintf(str,"Size : %dK", DL_Info.eFileSize/1024);
// LCD_Text(0,96,str,true,TFT_WHITE, TFT_BLACK,0xFF);
// // CRC
// DL_Info.eFileCRC = *(uint16_t*)&pIAP->pdata[2];
// sprintf(str,"CRC : 0x%04X", DL_Info.eFileCRC);
// LCD_Text(0,120,str,true,TFT_WHITE, TFT_BLACK,0xFF);
// // PCnt
// DL_Info.eFilePacket = *(uint32_t*)&pIAP->pdata[8];
}
IAP_CURR_STATE = IAP_STATE_DOWNLOAD_PACKET;
break;
case UFI_MODE_DOWN_ABORT:
// ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
case UFI_MODE_DOWN_FINISH:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IAP_CURR_STATE = IAP_STATE_IDEL;
break;
case UFI_MODE_DOWN_VERIFY:
// У<><D0A3> FLASH
IAP_CURR_STATE = IAP_STATE_VERIFY_PACKET;
break;
case UFI_MODE_REBOOT:
IAP_CURR_STATE = IAP_STATE_REBOOT;
break;
}
}
else
{
// <20><><EFBFBD><EFBFBD> format Disk 0 <20>ŵ<EFBFBD>д<EFBFBD><D0B4>
return USB_FAIL;
}
}
else if((addr >= 0x00108000)&&(addr < 0x00140000))
{
if(IAP_CURR_STATE == IAP_STATE_DOWNLOAD_PACKET)
{
if(addr == 0x00108000)
{
// LCD_Text(0,168,"FW DL ",true,TFT_WHITE, TFT_BLACK,0xFF);
// LCD_drawRoundRect(16,200,208,24,5,TFT_WHITE);
// // LCD_fillRoundRect(20,178,200,20,5,TFT_WHITE);//<2F><><EFBFBD><EFBFBD>
// LCD_TextCenter(228,"0%",true,TFT_WHITE, TFT_BLACK,0xFF);
}
else
{
// Percentage = ((addr - 0x00108000) / 4096) * 100 / (DL_Info.iFilePacket-1);
// sprintf(str,"%d%%", Percentage);
// LCD_fillRoundRect(20,204,2*Percentage,16,5,TFT_WHITE);//<2F><><EFBFBD><EFBFBD>
// LCD_TextCenter(228,str,true,TFT_WHITE, TFT_BLACK,0xFF);
}
flash_write( 0x08000000 + (addr - 0x00100000),buf,len);
}
}
else if((addr >= 0x01000000)&&(addr < 0x02000000))
{
if(IAP_CURR_STATE == IAP_STATE_DOWNLOAD_PACKET)
{
if(addr == 0x01000000)
{
// LCD_Text(0,168,"RES DL ",true,TFT_WHITE, TFT_BLACK,0xFF);
// LCD_drawRoundRect(16,200,208,24,5,TFT_WHITE);
// // LCD_fillRoundRect(20,178,200,20,5,TFT_WHITE);//<2F><><EFBFBD><EFBFBD>
// LCD_TextCenter(228,"0%",true,TFT_WHITE, TFT_BLACK,0xFF);
}
else
{
// Percentage = ((addr - 0x01000000) / 4096) * 100 / (DL_Info.eFilePacket-1);
// sprintf(str,"%d%%", Percentage);
// LCD_fillRoundRect(20,204,2*Percentage,16,5,TFT_WHITE);//<2F><><EFBFBD><EFBFBD>
// LCD_TextCenter(228,str,true,TFT_WHITE, TFT_BLACK,0xFF);
}
// flash_spi_write(buf,(addr-0x01000000),len);
W25Q128_Erase_Sector((addr-0x01000000));
W25Q128_Write(buf,(addr-0x01000000),len);
}
}
#endif
break;
case 1:
break;
}
return USB_OK;
}
/**
* @brief disk capacity
* @param lun: logical units number
* @param blk_nbr: pointer to number of block
* @param blk_size: pointer to block size
* @retval status of usb_sts_type
*/
int8_t msc_disk_capacity(uint8_t lun, uint32_t *blk_nbr, uint32_t *blk_size)
{
switch(lun)
{
case 0:
#if MountDisk
/* 普通 U 盘模式:直接把 W25Q128 (16MB) 挂出来 */
*blk_nbr = (uint32_t)(0x01000000 / 0x1000);
*blk_size = 0x1000;
#else
/* IAP 虚拟磁盘模式 (32MB):
- 0x00000000 : 命令/信息块 (RYAN 签名)
- 0x00100000~0x00140000 : 固件区 -> 内部 flash 0x08000000+
- 0x01000000~0x02000000 : 资源区 -> W25Q128 0x00000000+
容量必须覆盖到资源区末端 0x01FFFFFF,故取 0x02000000 */
*blk_nbr = (uint32_t)(0x02000000 / 0x1000);
*blk_size = 0x1000;
#endif
break;
default:
break;
}
return USB_OK;
}
/**
* @}
*/
/**
* @}
*/