mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-20 14:55:09 +03:00
FIRMWARE.BIN now exported in Taranis massstorage
This commit is contained in:
parent
2443b27b72
commit
692b13bba5
4 changed files with 224 additions and 198 deletions
|
@ -79,14 +79,6 @@
|
|||
#define BOOTLOADER_TITLE "Boot Loader - Sky9x"
|
||||
#endif
|
||||
|
||||
#define BOOTLOADER_SIZE 0x8000
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define FIRMWARE_ADDRESS 0x08000000
|
||||
#elif defined(PCBSKY9X)
|
||||
#define FIRMWARE_ADDRESS 0x00400000
|
||||
#endif
|
||||
|
||||
// states
|
||||
enum BootLoaderStates {
|
||||
ST_START,
|
||||
|
@ -211,15 +203,12 @@ uint32_t isFirmwareStart( uint32_t *block )
|
|||
|
||||
uint32_t (*IAP_Function)(uint32_t, uint32_t);
|
||||
|
||||
uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes
|
||||
void writeFlash(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
||||
{
|
||||
uint32_t FlashSectorNum;
|
||||
uint32_t flash_cmd = 0;
|
||||
uint32_t i;
|
||||
// uint32_t flash_status = 0;
|
||||
// uint32_t EFCIndex = 0; // 0:EEFC0, 1: EEFC1
|
||||
/* Initialize the function pointer (retrieve function address from NMI vector) */
|
||||
|
||||
/* Initialize the function pointer (retrieve function address from NMI vector) */
|
||||
if ((uint32_t) address == FIRMWARE_START+BOOTLOADER_SIZE) {
|
||||
if (isFirmwareStart(buffer))
|
||||
FlashBlocked = 0;
|
||||
|
@ -228,7 +217,7 @@ uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes
|
|||
}
|
||||
|
||||
if (FlashBlocked) {
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Always initialise this here, setting a default doesn't seem to work
|
||||
|
@ -238,8 +227,7 @@ uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes
|
|||
FlashSectorNum &= 2047;// max page number
|
||||
|
||||
/* Send data to the sector here */
|
||||
for ( i = 0; i < 64; i += 1 )
|
||||
{
|
||||
for (int i=0; i<FLASH_PAGESIZE/4; i++) {
|
||||
*address++ = *buffer++;
|
||||
}
|
||||
|
||||
|
@ -248,9 +236,8 @@ uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes
|
|||
|
||||
__disable_irq();
|
||||
/* Call the IAP function with appropriate command */
|
||||
i = IAP_Function( 0, flash_cmd );
|
||||
i = IAP_Function(0, flash_cmd);
|
||||
__enable_irq();
|
||||
return i;
|
||||
}
|
||||
|
||||
uint32_t readLockBits()
|
||||
|
@ -419,7 +406,7 @@ void eraseSector(uint32_t sector)
|
|||
FLASH->CR &= SECTOR_MASK;
|
||||
}
|
||||
|
||||
uint32_t program(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
||||
void writeFlash(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
@ -433,7 +420,7 @@ uint32_t program(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
|||
}
|
||||
|
||||
if (FlashBlocked) {
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((uint32_t) address == 0x08008000) {
|
||||
|
@ -477,13 +464,12 @@ uint32_t program(uint32_t *address, uint32_t *buffer) // size is 256 bytes
|
|||
/* Check the written value */
|
||||
if (*address != *buffer) {
|
||||
/* Flash content doesn't match SRAM content */
|
||||
return 2;
|
||||
return;
|
||||
}
|
||||
/* Increment FLASH destination address */
|
||||
address += 1;
|
||||
buffer += 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -873,11 +859,11 @@ int main()
|
|||
uint32_t blockOffset = 0;
|
||||
lcd_putsLeft(4*FH, "\032Loading...");
|
||||
while (BlockCount) {
|
||||
program((uint32_t *) firmwareAddress, &Block_buffer[blockOffset]); // size is 256 bytes
|
||||
blockOffset += 64; // 32-bit words (256 bytes)
|
||||
firmwareAddress += 256;
|
||||
if (BlockCount > 256) {
|
||||
BlockCount -= 256;
|
||||
writeFlash((uint32_t *)firmwareAddress, &Block_buffer[blockOffset]);
|
||||
blockOffset += FLASH_PAGESIZE/4; // 32-bit words
|
||||
firmwareAddress += FLASH_PAGESIZE;
|
||||
if (BlockCount > FLASH_PAGESIZE) {
|
||||
BlockCount -= FLASH_PAGESIZE;
|
||||
}
|
||||
else {
|
||||
BlockCount = 0;
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
|
||||
extern uint16_t ResetReason;
|
||||
|
||||
#define BOOTLOADER_SIZE 0x8000
|
||||
#define FIRMWARE_SIZE (256*1024)
|
||||
#define FIRMWARE_ADDRESS 0x00400000
|
||||
|
||||
#if defined(REVA)
|
||||
#define GPIO_BUTTON_MENU PIOB->PIO_PDSR
|
||||
#define GPIO_BUTTON_EXIT PIOA->PIO_PDSR
|
||||
|
|
|
@ -51,6 +51,7 @@ extern "C" {
|
|||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dma.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_usart.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h"
|
||||
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h"
|
||||
|
@ -72,6 +73,10 @@ extern "C" {
|
|||
#include "audio_driver.h"
|
||||
#endif
|
||||
|
||||
#define FLASHSIZE 0x80000
|
||||
#define BOOTLOADER_SIZE 0x8000
|
||||
#define FIRMWARE_ADDRESS 0x08000000
|
||||
|
||||
#define PERI1_FREQUENCY 30000000
|
||||
#define PERI2_FREQUENCY 60000000
|
||||
#define TIMER_MULT_APB1 2
|
||||
|
@ -136,6 +141,10 @@ void delay_01us(uint16_t nb);
|
|||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_Pin)
|
||||
#endif
|
||||
|
||||
// Flash Write driver
|
||||
#define FLASH_PAGESIZE 256
|
||||
void writeFlash(uint32_t * address, uint32_t * buffer);
|
||||
|
||||
// Pulses driver
|
||||
void init_no_pulses(uint32_t port);
|
||||
void disable_no_pulses(uint32_t port);
|
||||
|
|
|
@ -139,7 +139,7 @@ int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_si
|
|||
{
|
||||
if (lun == 1) {
|
||||
*block_size = BLOCKSIZE;
|
||||
*block_num = EESIZE/BLOCKSIZE + 3 ;
|
||||
*block_num = 3 + EESIZE/BLOCKSIZE + FLASHSIZE/BLOCKSIZE;
|
||||
}
|
||||
else {
|
||||
if (!SD_CARD_PRESENT())
|
||||
|
@ -263,12 +263,12 @@ const char g_FATboot[BLOCKSIZE] =
|
|||
0xeb, 0x3c, 0x90, // Jump instruction.
|
||||
0x39, 0x58, 0x20, 0x54, 0x45, 0x41, 0x4D, 0x00, // OEM Name
|
||||
0x00, 0x02, // Bytes per sector
|
||||
0x01, // Sectors per FS cluster.
|
||||
0x08, // Sectors per FS cluster.
|
||||
0x01, 0x00, // Reserved sector count
|
||||
|
||||
0x01, // Number of FATs
|
||||
0x10, 0x00, // Number of root directory entries
|
||||
(EESIZE/BLOCKSIZE)+3, 0x00, // Total sectors = 131
|
||||
3+(EESIZE/BLOCKSIZE), (FLASHSIZE/BLOCKSIZE)>>8, // Total sectors
|
||||
0xf8, // Media descriptor
|
||||
0x01, 0x00, // Sectors per FAT table
|
||||
0x20, 0x00, // Sectors per track
|
||||
|
@ -320,7 +320,7 @@ const char g_FATboot[BLOCKSIZE] =
|
|||
const char g_FAT[BLOCKSIZE] =
|
||||
{
|
||||
0xF8, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xA0, 0x00, 0x0B,
|
||||
0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0x20, 0x01, 0x13, 0x40, 0x01, 0x15, 0x60,
|
||||
0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0xF0, 0xFF, 0x13, 0x40, 0x01, 0x15, 0x60,
|
||||
0x01, 0x17, 0x80, 0x01, 0x19, 0xA0, 0x01, 0x1B, 0xC0, 0x01, 0x1D, 0xE0, 0x01, 0x1F, 0x00, 0x02,
|
||||
0x21, 0x20, 0x02, 0x23, 0x40, 0x02, 0x25, 0x60, 0x02, 0x27, 0x80, 0x02, 0x29, 0xA0, 0x02, 0x2B,
|
||||
0xC0, 0x02, 0x2D, 0xE0, 0x02, 0x2F, 0x00, 0x03, 0x31, 0x20, 0x03, 0x33, 0x40, 0x03, 0x35, 0x60,
|
||||
|
@ -331,7 +331,8 @@ const char g_FAT[BLOCKSIZE] =
|
|||
0x61, 0x20, 0x06, 0x63, 0x40, 0x06, 0x65, 0x60, 0x06, 0x67, 0x80, 0x06, 0x69, 0xA0, 0x06, 0x6B,
|
||||
0xC0, 0x06, 0x6D, 0xE0, 0x06, 0x6F, 0x00, 0x07, 0x71, 0x20, 0x07, 0x73, 0x40, 0x07, 0x75, 0x60,
|
||||
0x07, 0x77, 0x80, 0x07, 0x79, 0xA0, 0x07, 0x7B, 0xC0, 0x07, 0x7D, 0xE0, 0x07, 0x7F, 0x00, 0x08,
|
||||
0x81, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x81, 0x20, 0x08, 0x83, 0x40, 0x08, 0x85, 0x60, 0x08, 0x87, 0x80, 0x08, 0x89, 0xA0, 0x08, 0x8B,
|
||||
0xC0, 0x08, 0x8D, 0xE0, 0x08, 0x8F, 0x00, 0x09, 0x91, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -354,13 +355,19 @@ const char g_FAT[BLOCKSIZE] =
|
|||
#else
|
||||
const char g_FAT[BLOCKSIZE] =
|
||||
{
|
||||
0xF8, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xA0, 0x00, 0x0B,
|
||||
0xF8, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xF0, 0xFF, 0x0B,
|
||||
0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0x20, 0x01, 0x13, 0x40, 0x01, 0x15, 0x60,
|
||||
0x01, 0x17, 0x80, 0x01, 0x19, 0xA0, 0x01, 0x1B, 0xC0, 0x01, 0x1D, 0xE0, 0x01, 0x1F, 0x00, 0x02,
|
||||
0x21, 0x20, 0x02, 0x23, 0x40, 0x02, 0x25, 0x60, 0x02, 0x27, 0x80, 0x02, 0x29, 0xA0, 0x02, 0x2B,
|
||||
0xC0, 0x02, 0x2D, 0xE0, 0x02, 0x2F, 0x00, 0x03, 0x31, 0x20, 0x03, 0x33, 0x40, 0x03, 0x35, 0x60,
|
||||
0x03, 0x37, 0x80, 0x03, 0x39, 0xA0, 0x03, 0x3B, 0xC0, 0x03, 0x3D, 0xE0, 0x03, 0x3F, 0x00, 0x04,
|
||||
0x41, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x41, 0x20, 0x04, 0x43, 0x40, 0x04, 0x45, 0x60, 0x04, 0x47, 0x80, 0x04, 0x49, 0xA0, 0x04, 0x4B,
|
||||
0xC0, 0x04, 0x4D, 0xE0, 0x04, 0x4F, 0x00, 0x05, 0x51, 0x20, 0x05, 0x53, 0x40, 0x05, 0x55, 0x60,
|
||||
0x05, 0x57, 0x80, 0x05, 0x59, 0xA0, 0x05, 0x5B, 0xC0, 0x05, 0x5D, 0xE0, 0x05, 0x5F, 0x00, 0x06,
|
||||
0x61, 0x20, 0x06, 0x63, 0x40, 0x06, 0x65, 0x60, 0x06, 0x67, 0x80, 0x06, 0x69, 0xA0, 0x06, 0x6B,
|
||||
0xC0, 0x06, 0x6D, 0xE0, 0x06, 0x6F, 0x00, 0x07, 0x71, 0x20, 0x07, 0x73, 0x40, 0x07, 0x75, 0x60,
|
||||
0x07, 0x77, 0x80, 0x07, 0x79, 0xA0, 0x07, 0x7B, 0xC0, 0x07, 0x7D, 0xE0, 0x07, 0x7F, 0x00, 0x08,
|
||||
0x81, 0x20, 0x08, 0x83, 0x40, 0x08, 0x85, 0x60, 0x08, 0x87, 0x80, 0x08, 0x89, 0xF0, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -380,12 +387,6 @@ const char g_FAT[BLOCKSIZE] =
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -435,7 +436,7 @@ const FATDirEntry_t g_DIRroot[16] =
|
|||
0x00000000
|
||||
},
|
||||
{
|
||||
{ 'T', 'A', 'R', 'A', 'N', 'I', 'S', ' '},
|
||||
{ 'E', 'E', 'P', 'R', 'O', 'M', ' ', ' '},
|
||||
{ 'B', 'I', 'N'},
|
||||
0x24, // Archive, hidden, system
|
||||
0x00,
|
||||
|
@ -450,19 +451,19 @@ const FATDirEntry_t g_DIRroot[16] =
|
|||
EESIZE
|
||||
},
|
||||
{
|
||||
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
|
||||
{ ' ', ' ', ' '},
|
||||
0x00,
|
||||
0x00,
|
||||
{ 'F', 'I', 'R', 'M', 'W', 'A', 'R', 'E'},
|
||||
{ 'B', 'I', 'N'},
|
||||
0x24, // Archive, hidden, system
|
||||
0x00,
|
||||
0x3E,
|
||||
0xA301,
|
||||
0x3D55,
|
||||
0x3D55,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x00000000
|
||||
0xA302,
|
||||
0x3D55,
|
||||
0x0002 + (EESIZE/BLOCKSIZE)/8,
|
||||
FLASHSIZE
|
||||
},
|
||||
{
|
||||
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
|
||||
|
@ -667,33 +668,42 @@ int32_t fat12Read( uint8_t *buffer, uint16_t sector, uint16_t count )
|
|||
while ( count )
|
||||
{
|
||||
if (sector == 0) {
|
||||
memcpy( buffer, g_FATboot, BLOCKSIZE ) ;
|
||||
memcpy(buffer, g_FATboot, BLOCKSIZE ) ;
|
||||
}
|
||||
else if (sector == 1/*Reserved sector count*/) {
|
||||
// FAT table.
|
||||
memcpy( buffer, g_FAT, BLOCKSIZE);
|
||||
memcpy(buffer, g_FAT, BLOCKSIZE);
|
||||
}
|
||||
else if (sector == 2) {
|
||||
memcpy( buffer, g_DIRroot, BLOCKSIZE ) ;
|
||||
memcpy(buffer, g_DIRroot, BLOCKSIZE ) ;
|
||||
}
|
||||
else {
|
||||
else if (sector < 3 + (EESIZE/BLOCKSIZE)) {
|
||||
eeprom_read_block (buffer, (sector-3)*BLOCKSIZE, BLOCKSIZE);
|
||||
}
|
||||
else if (sector < 3 + (EESIZE/BLOCKSIZE) + (FLASHSIZE/BLOCKSIZE)) {
|
||||
uint32_t address;
|
||||
address = sector - 3 - (EESIZE/BLOCKSIZE);
|
||||
address *= BLOCKSIZE;
|
||||
address += FIRMWARE_ADDRESS;
|
||||
memcpy(buffer, (uint8_t *)address, BLOCKSIZE);
|
||||
}
|
||||
buffer += BLOCKSIZE ;
|
||||
sector++ ;
|
||||
count-- ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int32_t fat12Write(const uint8_t *buffer, uint16_t sector, uint32_t count )
|
||||
{
|
||||
static int offset = 0;
|
||||
|
||||
TRACE("FAT12 Write(sector=%d, count=%d)", sector, count);
|
||||
|
||||
if (sector < 3) {
|
||||
// reserved, read-only
|
||||
}
|
||||
else if (sector < 3 + (EESIZE/BLOCKSIZE)) {
|
||||
while (count) {
|
||||
const EeFs * test = (const EeFs *)buffer;
|
||||
if (offset == 0 && test->version==EEFS_VERS && test->mySize==sizeof(eeFs) && test->bs==BS) {
|
||||
|
@ -711,9 +721,26 @@ int32_t fat12Write(const uint8_t *buffer, uint16_t sector, uint32_t count )
|
|||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sector < 3 + (EESIZE/BLOCKSIZE) + (FLASHSIZE/BLOCKSIZE)) {
|
||||
// firmware
|
||||
uint32_t address;
|
||||
address = sector - 3 - (EESIZE/BLOCKSIZE);
|
||||
address *= BLOCKSIZE;
|
||||
address += FIRMWARE_ADDRESS;
|
||||
|
||||
while (count) {
|
||||
for (uint32_t i=0; i<BLOCKSIZE/FLASH_PAGESIZE; i++) {
|
||||
if (address >= FIRMWARE_ADDRESS+BOOTLOADER_SIZE/*protect bootloader*/ && address <= FIRMWARE_ADDRESS+FLASHSIZE-FLASH_PAGESIZE) {
|
||||
writeFlash((uint32_t *)address, (uint32_t *)buffer);
|
||||
}
|
||||
address += FLASH_PAGESIZE;
|
||||
buffer += FLASH_PAGESIZE;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue