⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nf_loader.c

📁 mp3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif

//! Init to make it possible the resumes of a loading by dfc transfert
//!
//! @param   none
//! @return  none
//! 
void nfloader_init_resume_module( void )
{
   // Prepare NFC for the next DFC flow
   Nfc_action( NFC_ACT_STOP, 0 );   // Ensures NFC is idle

   // Configure NFC/DFC transfer mode.
   Nfc_mode_manual();
   Nfc_clear_it_all();  // Clear all its.
}

//! Resume the loading of a NF page by dfc transfert
//!
//! @param   none
//! @return  none
//!
void nfloader_resume_module( void )
{
   if( Is_nfc_running() ) return;

   if(0 == s_mod_hdl.nb_pages)
   {
      s_mod_hdl.i_frag++;
      // Load device_number, page_addr and nb_pages
      Nfloader_load_hdl();          
   }   

   Mcu_set_sfr_page_nfc();
   Nfc_action( NFC_ACT_DEV_SELECT, s_mod_hdl.device_number );

   // NOTE : for the firmware zone, the offset may be != 0 for the first sector
   // loading. For the next sectors, the offset is 0 => s_mod_hdl.offset = 0;
   nfc_open_page_read( s_mod_hdl.page_addr, s_mod_hdl.offset );
   s_mod_hdl.offset = 0;

   Nfc_action( NFC_ACT_READ, 0 );
   s_mod_hdl.page_addr++;
   s_mod_hdl.nb_pages--;
}


//! Read version of codec
//!
//! @param   buffer to store version
//! @return  none
//!
void nfloader_read_version( U8 _MEM_TYPE_SLOW_ *buffer )
{
   U16 u16_i;
   U8  u8_i;

   Mcu_set_sfr_page_nfc();
   Nfc_action( NFC_ACT_DEV_SELECT, s_mod_hdl.device_number );
   nfc_open_page_read( s_mod_hdl.page_addr, s_mod_hdl.offset );
   for( u16_i=0x100+18+1; u16_i!=0 ; u16_i-- )
   {  // +100h offset version ; +18 not read text version ; +1 Dummy read
      ACC= Nfc_rd_data_fetch_next();
   }
   for( u8_i=6; u8_i!=0 ; u8_i-- )
   {  // read "x.x.xx"
      *buffer = Nfc_rd_data_fetch_next();
      buffer++;
   }
   *buffer = 0;
}


//! Compute the physic address of the logical address 0 in the current module
//!
//! @param  none
//! @return none
//!
void nfloader_compute_physic_addr_0( void )
{
   s_mod_hdl.nb_frag       = s_module.nb_frag;  // Information just for debug information
   s_mod_hdl.i_frag        = 0;
   s_mod_hdl.offset        = 0;
   // Compute device_number, page_addr and nb_pages in s_mod_hdl.offset
   Nfloader_load_hdl();                  
   s_mod_hdl.page_addr     += (U32) s_module.start_page;
}

//! Compute the physic address of the logical address in the current module
//! In the worst case (NF512), the logical address is limited to 2^16 page addr * 512 => 33MB
//!
//! @param  U32 log_addr : logical address on the module data section
//! @return status PASS or FAIL
//!
U8 nfloader_compute_physic_addr( U32 log_addr )
{
   _MEM_TYPE_FAST_ Fragment _MEM_TYPE_SLOW_* ptr_frag;
   _MEM_TYPE_FAST_ U32 fast_log_addr;

   fast_log_addr = log_addr;
   // Determinate the logical page from the logical address
   #define  U16_LOGICAL_PAGE    LSW(s_mod_hdl.page_addr)  // -> 2^16 page addr max
   MSW(s_mod_hdl.page_addr) = 0;

   U16_LOGICAL_PAGE  = (fast_log_addr >> NF_SHIFT_PAGE_BYTE); // More efficient than division by NF_NB_BYTE_PER_PAGE


   // Determinate the fragment that contains this logical page
   s_mod_hdl.i_frag = 0;
   ptr_frag = &s_module.frag[0];

   while( U16_LOGICAL_PAGE >= ptr_frag->nb_pages )
   {
      U16_LOGICAL_PAGE -= ptr_frag->nb_pages;
      if( MAX_NB_FRAGMENTS == ++s_mod_hdl.i_frag )
         { return FAIL; }
      else
         { ptr_frag++; }
   }
   
   // Secondly, compute the page address and the offset from the logical page and the fragment
   s_mod_hdl.offset        = fast_log_addr % (U32) NF_NB_BYTE_PER_PAGE;
   // Value of the parameter "fast_log_addr" no more useful. Thus "fast_log_addr" is used below as temporary variable.
   #define VAR_TEMP_32  fast_log_addr
   LSW(VAR_TEMP_32)  = ptr_frag->nb_pages - U16_LOGICAL_PAGE;
   // More than 256 pages to read before reaching the end of the current fragment i.e. 128KB with NF512.
   // In any customer application, a single read might not exceed 128KB.
   // So, s_mod_hdl.nb_pages = 0xFF if LSW(fast_log_addr) > 0x00FF.
   if( LSB1(VAR_TEMP_32) != 0x00 )  { s_mod_hdl.nb_pages = 0xFF;           }
   else                             { s_mod_hdl.nb_pages = LSB0(VAR_TEMP_32); }

   VAR_TEMP_32 = ptr_frag->block_addr << NF_SHIFT_BLOCK_PAGE;
   if( 0 == s_mod_hdl.i_frag )
      { VAR_TEMP_32 += (U32) s_module.start_page; }
   s_mod_hdl.page_addr += VAR_TEMP_32; 

   s_mod_hdl.device_number = ptr_frag->device_number;
   s_mod_hdl.nb_frag       = s_module.nb_frag;     // Information just for debug information

   return PASS;
}

//! Get the unaligned bytes
//! Be careful: "s_mod_hdl.offset" is only incremented in "nfloader_get_data_and_fetch_next_one()"
//!
//! @param  void
//! @return U16  nb of bytes unaligned
//!
#if (defined BOARD_REFD1)
U16 nfloader_get_unaligned_bytes( void )
{
   return NF_NB_BYTE_PER_PAGE-s_mod_hdl.offset;
}
#endif

//! Open the next NF page at offset 0 for reading
//!
//! @param  none
//! @return none
//!
#if (defined BOARD_REFD1)
void nfloader_open_next_page( void )
{
   Mcu_set_sfr_page_nfc();
   
   
   if( 0 == --s_mod_hdl.nb_pages )
   {
      s_mod_hdl.i_frag++;
      // Load device_number, page_addr and nb_pages
      Nfloader_load_hdl();          
   }
   else
   {
      s_mod_hdl.offset = 0;
      s_mod_hdl.page_addr++;
   }

   nfloader_open_page_for_reading_via_register();
}
#endif

//! Get the data at the current position in NF
//! and increment this position to prepare the next read
//!
//! @param  none
//! @return U8  the data byte read
//!
U8 nfloader_get_data_and_fetch_next_one( void )
{
   // Test if the previous fetch is wrong because of the end of NF page
   if( NF_NB_BYTE_PER_PAGE == s_mod_hdl.offset++ )
   {
      s_mod_hdl.offset = 0;
      if( 0 == --s_mod_hdl.nb_pages )
      {
         s_mod_hdl.i_frag++;
         // Load device_number, page_addr and nb_pages
         Nfloader_load_hdl();          
      }
      else
      { s_mod_hdl.page_addr++; }

      nfloader_open_page_for_reading_via_register();
      s_mod_hdl.offset = 1;
   }

   // Return the current data and fetch the next one
   return( Nfc_rd_data_fetch_next() );
}

//! Open a NF page for reading via register
//!
//! @param  none
//! @return none
//!
void nfloader_open_page_for_reading_via_register( void )
{
   Nfc_action(NFC_ACT_DEV_SELECT, s_mod_hdl.device_number);
   nfc_open_page_read(s_mod_hdl.page_addr, s_mod_hdl.offset);
   ACC = Nfc_rd_data_fetch_next();  // Dummy read required when manual reads
}

#if (FUNC_UPDATE == ENABLE) 
#  if (UPDATE_DO_FW_COPY == ENABLE)
//! Check FW and FW copy zone
//! @return status
//!    TRUE       -> the CRC is OK
//!    FALSE      -> the CRC is bad. Then s_zone_page_addr[] tab is modified
//!
Bool nfloader_ckeck_fw_crc( void )
{
   U8    zone;
   U8    u8_i;
   U8    bank_save;
   U32   u32_page_addr;
   
   // Not necessary to check CRC if there is no copy of the FW, because it will not possible to copy it if bad!
   if (UNFOUND_PATTERN == s_zone_page_addr[ZONE_FIRMWARE_COPY]   )
   { 
      // Will copie ZONE_FIRMWARE (which is considered as good) in update task if not updating      
      return FALSE; 
   }  
   else
   {   
      if (PASS == nfloader_init_load_module(0,ZONE_FIRMWARE))  
      {                  
         if (MAPNF_FW_OPT_DFC_CRC & s_module.option)
         {
            // Save current Bank
            bank_save = g_current_bank;
            u32_page_addr = s_zone_page_addr[ZONE_FIRMWARE_COPY]; 

            //for ZONE_FIRMWARE and ZONE_FIRMWARE_COPY
            for (zone=0; zone<2;zone++)
            {
               for (u8_i=1; u8_i<MAX_MODULE_PER_ZONE; u8_i++)   // start with the first bank (bank 1) 
      	      {                
                  // does not run Bank_load() function if the bank does not exist! 
                  if (PASS == nfloader_init_load_module(u8_i,ZONE_FIRMWARE))
                  {
                     g_current_bank = u8_i;
                     Bank_load();      // Load bank and uncipher it if necessary
                     if (FALSE == nfloader_check_bank_crc())
                     {
                        // The copy routine copy ZONE_FIRMWARE in new one, so swap it if ZONE_FIRMWARE is bad
                        // to copy the actual ZONE_FIRMWARE_COPY into ZONE_FIRMWARE  
                        s_zone_page_addr[ZONE_FIRMWARE] = u32_page_addr;
                        s_zone_page_addr[ZONE_FIRMWARE_COPY] = UNFOUND_PATTERN;
                                         
                        // Restore previous Bank
                        g_current_bank = bank_save;
                        Bank_load();               
                        // Will copie ZONE_FIRMWARE (which is considered as good) in update task
                        return FALSE;
                     }
                  }
               }
               if(ZONE_FIRMWARE==zone)
               {
                  u32_page_addr = s_zone_page_addr[ZONE_FIRMWARE]; 
                  s_zone_page_addr[ZONE_FIRMWARE] = s_zone_page_addr[ZONE_FIRMWARE_COPY];}
               }
            } 
#warning Bad CRC in FW zone not tested yet!
         // Restore saved value if all is right
         s_zone_page_addr[ZONE_FIRMWARE] = u32_page_addr;
         // Restore previous Bank
         g_current_bank = bank_save;
         Bank_load();
      }
   }
   return TRUE;
}

//! Calcul the CRC of module in RAM
//! @return status
//!    TRUE       -> the CRC is OK
//!    FALSE      -> the CRC is bad
//!
Bool nfloader_check_bank_crc( void )    
{
   U16 u16_add_xram = 0;                           // start calcul at the beginning of cdata

   Mcu_set_sfr_page_dfc();
   Dfc_reset();
   Dfc_enable();
   Dfc_crc_enable();
   Dfc_crc16_init( u16_add_xram );
   Dfc_set_adr_cram( u16_add_xram );               // Init interface DFC of C51 XRAM
   Dfc_prog_ch_0( DFC_ID_C51_RAM );                // Init source
   Dfc_prog_ch_0( DFC_ID_NULL_DEV );               // Init Dest
   Dfc_prog_ch_0( 0 );                             // packet = 1 Byte

   Dfc_prog_ch_0( ((U16)(s_module.true_size + BANK_START_ADDRESS))>>8   ); // + BANK_START_ADDRESS cause to the crc include the startup code!
   Dfc_prog_ch_0( ((U16)(s_module.true_size + BANK_START_ADDRESS))&0xFF );
 
   while( Is_dfc_ch_0_busy() );                    // Wait end of CRC compute (= end of transfer)

   Dfc_crc16_read( u16_add_xram );
   return (u16_add_xram == (U16) s_module.CRC);
}
#  endif   //#if (UPDATE_DO_FW_COPY == ENABLE)


#  if (UPDATE_DO_CODEC_COPY == ENABLE)
//! Check COdec and COdec copy zone
//! @return status
//!    TRUE       -> the CRC is OK
//!    FALSE      -> the CRC is bad. Then s_zone_page_addr[] tab is modified
//!
Bool nfloader_check_codec_crc( void )
{
   U8    u8_i;
   U32   u32_page_addr;                                      
                    
   if (UNFOUND_PATTERN == s_zone_page_addr[ZONE_CODEC_COPY]   )
   { 
      // Will copie ZONE_CODEC (which is considered as good) in update task if not updating
      return FALSE; 
   } 
   else
   {
      nfup_get_zone_info(ZONE_CODEC);  // Fill in g_zone_info
      for(u8_i=0;u8_i<g_zone_info.u8_nb_module;u8_i++)
      {
         codec_load(g_zone_info.module[u8_i].u8_type);
         if (!nfloader_is_codec_crc_is_good((U16)g_zone_info.module[u8_i].u32_crc))
         {
            s_zone_page_addr[ZONE_CODEC] = s_zone_page_addr[ZONE_CODEC_COPY];
            s_zone_page_addr[ZONE_CODEC_COPY] = UNFOUND_PATTERN;                
            // Reset id in order to force to reload codec
            s_curr_zone_id   = 0xFF;
   
            // Reset loading pointer of audio proc
            Aup_enable();
            Aup_disable();
            return FALSE;
         }
      }
     
      u32_page_addr = s_zone_page_addr[ZONE_CODEC]; 
      s_zone_page_addr[ZONE_CODEC] = s_zone_page_addr[ZONE_CODEC_COPY];

      nfup_get_zone_info(ZONE_CODEC);  // Fill in g_zone_info
      for(u8_i=0;u8_i<g_zone_info.u8_nb_module;u8_i++)
      {
         codec_load(g_zone_info.module[u8_i].u8_type);
         if (!nfloader_is_codec_crc_is_good((U16)g_zone_info.module[u8_i].u32_crc))
         {
            s_zone_page_addr[ZONE_CODEC] = u32_page_addr;
            s_zone_page_addr[ZONE_CODEC_COPY] = UNFOUND_PATTERN;               
            // Reset id in order to force to reload codec
            s_curr_zone_id   = 0xFF;   
            // Reset loading pointer of audio proc
            Aup_enable();
            Aup_disable();
            return FALSE;
         }
      } 
      s_zone_page_addr[ZONE_CODEC] = u32_page_addr; 
   }
   // Reset id in order to force to reload codec
   s_curr_zone_id   = 0xFF;
   
   // Reset loading pointer of audio proc
   Aup_enable();
   Aup_disable();
   return TRUE;
}

//! Compare DFC CRC and CRC passed by parameter
//! @return status
//!    TRUE       -> the CRC is OK
//!    FALSE      -> the CRC is bad
//!

Bool nfloader_is_codec_crc_is_good( U16 u16_crc )
{
   U16 u16_add_xram;  
   
   Dfc_crc16_read( u16_add_xram );
   return (u16_add_xram == u16_crc);
}    
#  endif   // #if (UPDATE_DO_CODEC_COPY == ENABLE)
#endif   //#if (FUNC_UPDATE == ENABLE)

#endif // #ifdef _nf_loader_c_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -