support uf2 for msc
This commit is contained in:
		| @@ -64,7 +64,6 @@ | |||||||
|         <file file_name="../usb/tusb_descriptors.c" /> |         <file file_name="../usb/tusb_descriptors.c" /> | ||||||
|         <file file_name="../usb/tusb_descriptors.h" /> |         <file file_name="../usb/tusb_descriptors.h" /> | ||||||
|         <folder Name="uf2"> |         <folder Name="uf2"> | ||||||
|           <file file_name="../usb/uf2/ghostfat.c" /> |  | ||||||
|           <file file_name="../usb/uf2/uf2cfg.h" /> |           <file file_name="../usb/uf2/uf2cfg.h" /> | ||||||
|           <file file_name="../usb/uf2/uf2.h" /> |           <file file_name="../usb/uf2/uf2.h" /> | ||||||
|         </folder> |         </folder> | ||||||
|   | |||||||
| @@ -43,6 +43,9 @@ | |||||||
| // for formatting fatfs when Softdevice is not enabled | // for formatting fatfs when Softdevice is not enabled | ||||||
| #include "nrf_nvmc.h" | #include "nrf_nvmc.h" | ||||||
|  |  | ||||||
|  | #include "uf2/uf2.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| /*------------------------------------------------------------------*/ | /*------------------------------------------------------------------*/ | ||||||
| /* MACRO TYPEDEF CONSTANT ENUM | /* MACRO TYPEDEF CONSTANT ENUM | ||||||
|  *------------------------------------------------------------------*/ |  *------------------------------------------------------------------*/ | ||||||
| @@ -410,9 +413,9 @@ typedef ATTR_PACKED_STRUCT(struct) { | |||||||
|   uint16_t written_date; |   uint16_t written_date; | ||||||
|   uint16_t cluster_low; |   uint16_t cluster_low; | ||||||
|   uint32_t file_size; |   uint32_t file_size; | ||||||
| }fat_directory_t; | }fat_dirent_t; | ||||||
|  |  | ||||||
| VERIFY_STATIC(sizeof(fat_directory_t) == 32, "size is not correct"); | VERIFY_STATIC(sizeof(fat_dirent_t) == 32, "size is not correct"); | ||||||
|  |  | ||||||
|  |  | ||||||
| fat12_boot_sector_t const _boot_sect = | fat12_boot_sector_t const _boot_sect = | ||||||
| @@ -466,17 +469,47 @@ fat12_boot_sector_t const _boot_sect = | |||||||
| static inline bool fat12_formatted(void) | static inline bool fat12_formatted(void) | ||||||
| { | { | ||||||
|   const uint8_t* boot_sect = (uint8_t* ) lba2addr(0); |   const uint8_t* boot_sect = (uint8_t* ) lba2addr(0); | ||||||
|   return (boot_sect[510] == 0x55) && (boot_sect[511] == 0xAA); |   return false; | ||||||
|  |   //return (boot_sect[510] == 0x55) && (boot_sect[511] == 0xAA); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void fat12_write_sector(uint32_t lba, uint8_t const* buf, uint32_t bufsize) | static void fat12_write_sector(uint32_t sect, uint8_t const* buf, uint32_t bufsize) | ||||||
| { | { | ||||||
|   uint32_t addr = lba2addr(lba); |   uint32_t addr = lba2addr(sect); | ||||||
|  |  | ||||||
|   nrf_nvmc_page_erase( addr ); |   nrf_nvmc_page_erase( addr ); | ||||||
|   nrf_nvmc_write_words(addr, (uint32_t const*) buf, bufsize/4); |   nrf_nvmc_write_words(addr, (uint32_t const*) buf, bufsize/4); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const char infoUf2File[] = // | ||||||
|  |     "UF2 Bootloader " UF2_VERSION "\r\n" | ||||||
|  |     "Model: " PRODUCT_NAME "\r\n" | ||||||
|  |     "Board-ID: " BOARD_ID "\r\n"; | ||||||
|  |  | ||||||
|  | const char indexFile[] = // | ||||||
|  |     "<!doctype html>\n" | ||||||
|  |     "<html>" | ||||||
|  |     "<body>" | ||||||
|  |     "<script>\n" | ||||||
|  |     "location.replace(\"" INDEX_URL "\");\n" | ||||||
|  |     "</script>" | ||||||
|  |     "</body>" | ||||||
|  |     "</html>\n"; | ||||||
|  |  | ||||||
|  | uint8_t const readme_contents[] = "Adafruit Feather nRF52840"; | ||||||
|  |  | ||||||
|  | struct TextFile { | ||||||
|  |     const char name[11]; | ||||||
|  |     const char *content; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const struct TextFile info[] = { | ||||||
|  |     {.name = "INFO_UF2TXT", .content = infoUf2File}, | ||||||
|  |     {.name = "INDEX   HTM", .content = indexFile}, | ||||||
|  |     {.name = "CURRENT UF2", .content = readme_contents}, | ||||||
|  | }; | ||||||
|  |  | ||||||
| static void fat12_mkfs(void) | static void fat12_mkfs(void) | ||||||
| { | { | ||||||
|   memclr_(_page_cached, sizeof(_page_cached)); |   memclr_(_page_cached, sizeof(_page_cached)); | ||||||
| @@ -495,22 +528,23 @@ static void fat12_mkfs(void) | |||||||
|   fat12_write_sector(0, _page_cached, FL_PAGE_SIZE); |   fat12_write_sector(0, _page_cached, FL_PAGE_SIZE); | ||||||
|  |  | ||||||
|   //------------- Root Directory cluster -------------// |   //------------- Root Directory cluster -------------// | ||||||
|   uint8_t const readme_contents[] = "Adafruit Feather nRF52840"; |  | ||||||
|  |  | ||||||
|   memclr_(_page_cached, sizeof(_page_cached)); |   memclr_(_page_cached, sizeof(_page_cached)); | ||||||
|   fat_directory_t* p_entry = (fat_directory_t*) _page_cached; |   fat_dirent_t* p_entry = (fat_dirent_t*) _page_cached; | ||||||
|  |  | ||||||
|   // first entry is volume label |   // first entry is volume label | ||||||
|   (*p_entry) = (fat_directory_t) |   (*p_entry) = (fat_dirent_t) | ||||||
|   { |   { | ||||||
|     .name = MSC_FLASH_VOL_LABEL, |     .name = MSC_FLASH_VOL_LABEL, | ||||||
|     .attr.volume_label = 1, |     .attr.volume_label = 1, | ||||||
|   }; |   }; | ||||||
|  |   p_entry++; // next entry | ||||||
|  |  | ||||||
|   p_entry += 1; // advance to second entry, which is readme file |   uint16_t data_cluster = 2; // logical data cluster always start from 2 | ||||||
|   (*p_entry) = (fat_directory_t) |   for(int i=0; i<arrcount_(info); i++) | ||||||
|   { |   { | ||||||
|     .name = "README  TXT", |     (*p_entry) = (fat_dirent_t) | ||||||
|  |     { | ||||||
|  |       .name = { 0 }, | ||||||
|  |  | ||||||
|       .attr = { 0 }, |       .attr = { 0 }, | ||||||
|       .reserved = 0, |       .reserved = 0, | ||||||
| @@ -525,18 +559,28 @@ static void fat12_mkfs(void) | |||||||
|       .written_time = 0x6D52, |       .written_time = 0x6D52, | ||||||
|       .written_date = 0x4365, |       .written_date = 0x4365, | ||||||
|  |  | ||||||
|     .cluster_low = 2, |       .cluster_low = data_cluster, | ||||||
|     .file_size = sizeof(readme_contents)-1 // exclude NULL |       .file_size = strlen(info[i].content) | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     memcpy(p_entry->name, info[i].name, 11); | ||||||
|  |  | ||||||
|  |     data_cluster++; | ||||||
|  |     p_entry++; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Erase and Write cluster. |   // Erase and Write cluster. | ||||||
|   fat12_write_sector(8, _page_cached, FL_PAGE_SIZE); |   fat12_write_sector(8, _page_cached, FL_PAGE_SIZE); | ||||||
|  |  | ||||||
|   //------------- Readme Content cluster -------------// |   //------------- Data Contents -------------// | ||||||
|   memclr_(_page_cached, sizeof(_page_cached)); |   memclr_(_page_cached, sizeof(_page_cached)); | ||||||
|   memcpy(_page_cached, readme_contents, sizeof(readme_contents)-1); |  | ||||||
|  |  | ||||||
|   // Erase and Write cluster. |   for(int i=0; i<arrcount_(info); i++) | ||||||
|  |   { | ||||||
|  |     memcpy(_page_cached + i*512, info[i].content, strlen(info[i].content)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Erase and Write data cluster. | ||||||
|   fat12_write_sector(16, _page_cached, FL_PAGE_SIZE); |   fat12_write_sector(16, _page_cached, FL_PAGE_SIZE); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user