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

📄 bli2c.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************
 *
 * i2c.c
 *
 * CVS ID:   $Id: bli2c.c,v 1.7 2007/10/25 10:11:40 marcucci Exp $
 * Author:   Maurizio Marcucci [MM] - STM
 * Date:     $Date: 2007/10/25 10:11:40 $
 * Revision: $Revision: 1.7 $
 * 
 * Description:
 * 
 *   Low level I2C driver
 *
 ***************************************************
 * 
 * COPYRIGHT (C) ST Microelectronics  2005
 *            All Rights Reserved
 *
 ***************************************************
 *
 * STM CVS Log:
 *
 * $Log: bli2c.c,v $ * Revision 1.7  2007/10/25 10:11:40  marcucci * Enable SCL & SDA I2C lines only after complete I2C Hardware initilaization *
 * Revision 1.6  2007/09/05 07:04:54  marcucci
 * Debug Variable deleted
 *
 * Revision 1.5  2007/07/11 10:12:04  marcucci
 * Set BUSY condition on I2C Start Detection  and I2C emergency Init added
 *
 * Revision 1.4  2007/07/04 14:22:43  marcucci
 * Continuous Data Transfer Added
 *
 * Revision 1.3  2007/07/03 06:45:36  marcucci
 * Added Comments
 *
 * Revision 1.2  2007/07/02 14:56:43  marcucci
 * Fixed Wrong Reference to bli2c.c file
 *
 * Revision 1.1  2007/07/02 08:42:59  marcucci
 * I2C Bootloader
 *
 * Revision 1.8  2006/12/19 17:06:00  belardi
 * Sends 0x00 if host requests more bytes than available in current packet
 *
 * Revision 1.7  2006/10/18 12:38:44  belardi
 * Removed USE_STM_HOSTIF
 *
 * Revision 1.6  2006/09/18 09:55:23  belardi
 * Corrected CVS keyword usage
 *
 * Revision 1.5  2006/09/18 09:24:13  belardi
 * Added Log CVS keyword into file header
 *
 *
 ***************************************************/
#include "configuration.h"
#include "blgendef.h"
#include "hwreg.h"

extern BL_STRUCT * bl;

uint32 bl_i2cFillDram(void);
extern void bl_PrepareDram4Dwl(uint32 bl_start_addr, uint32 bl_end_addr);

#define RWBIT_MASK 0x01

uint8 bl_i2c_cksum_verify(uint8 * msg_ptr);

__irq void bl_i2c_event_isr(void);
__irq void bl_i2c_xfer_isr(void);
extern void sdram_init(uint32 PATCH_TABLE_ADDRESS);
extern void Reset_Handler(uint32 PATCH_TABLE_ADDRESS);
#define	S_APB_CLK	67740000 //(67.74 MHZ)
/* Link layer message buffer for send and receive functions */
#define FM_I2C_CLK(clk)   (((S_APB_CLK/(clk)) - 9 ) / 3)
#define I2C_100kHz  100000
#define I2C_400kHz  400000

uint8 bl_i2c_cksum(uint8 * msg_ptr);
void bl_i2c_ack(uint8 err);
void bl_i2c_tx_msg(void);
extern void configure_gpio(unsigned int port, unsigned int bit, unsigned int function);
extern void bl_copy_jt(void);
extern void emergency_i2c_init(void);


/******************************************************************************/
/* Function:  i2c_soft_reset                                                  */
/*                                                                            */
/*! \brief    Initialize the I2C flags & Tx/Rx Buffers
 *  \param    void
 *  \return   void
 *  \remark
 */
/******************************************************************************/
void bl_i2c_soft_reset(void)
{
 uint32 i;

 bl->i2c_flags.msg_rcvd = 0;
 bl->i2c_flags.i2c_rx_ready = 1;
 bl->i2c_flags.i2c_tx_ready = 1;
 bl->i2c_flags.tx_msg_done = 1;
 bl->i2c_flags.i2c_new_cmd = 0;
 bl->i2c_irq_tx_buffer_idx = 0;
 bl->i2c_irq_rx_buffer_idx = 0;

 /* Initialize the buffers, only for debug */
 for(i = 0; i < BL_DEFAULT_MAX_I2C_TX_FRAME_SIZE; i++)
 {
  bl->i2c_irq_tx_buffer[i] = 0x00;
 }
 
 // Prepare Message MsgPowerMode: Patch Load Required
 bl->i2c_irq_tx_buffer[0] = 4;// Length
 bl->i2c_irq_tx_buffer[1] = 3;// GR 
 bl->i2c_irq_tx_buffer[2] = 1;// ID
 bl->i2c_irq_tx_buffer[3] = 4;// PAR: Patch Code Downloading
 bl->i2c_irq_tx_buffer[4] = bl_i2c_cksum(bl->i2c_irq_tx_buffer);
 
 for(i = 0; i < BL_DEFAULT_MAX_I2C_RX_FRAME_SIZE; i++)
 {
  bl->i2c_irq_rx_buffer[i] = 0x00;
 }

}

/******************************************************************************/
/* Function:  i2c_init                                                        */
/*                                                                            */
/*! \brief    Initialize the I2C hardware 
 *  \param    void
 *  \return   void
 *  \remark
 */
/******************************************************************************/
void bl_i2c_init(void)
{ 
 uint32 isr_addr;
 uint32 i;
 
 bl_i2c_soft_reset();
 
 bl->error.field.bad_starting_address = 0;
 bl->error.field.ram_verify = 0;
 bl->error.field.inv_op_code = 0;
 bl->error.field.inv_checksum = 0;
 bl->error.field.inv_param = 0;
 bl->error.field.bad_len = 0;
 
 bl->dwn_ctrl_flags.continous_xfer = 0;
 
 bl->code_size = 0;
 bl->code_checksum = 0;
 bl->max_addr = 0;
 
 bl->sdram_code_size = 0;       	           	
 bl->sdram_code_checksum = 0;	   
 bl->max_sdram_addr = 0;
 
 bl->start_address = 0;
 
 I2C0_CR.all = 0;

 /* Configure Frequency Bits to match I2C setup/hold times */
 I2C0_OAR2.field.fr = 6;   // Input Frequency 66-80Mhz

// I2C0_CCR.field.fm_sm = 0; // Standard I2C 
// I2C0_CCR.field.cc_0_6 = 0x32; // 10Khz I2C
// I2C0_ECCR = 0x1A;

 /* Clock Control Register */
 I2C0_CCR.field.fm_sm = 1; // Fast I2C
 I2C0_CCR.field.cc_0_6 = 0x6E; // 100Khz I2C  0xde = 100Khz
                               // 200Khz I2C  0x6E = 200Khz

 /* Extended Clock Control Register */
 /* set the clock divider along with I2C_CCR register */
 I2C0_ECCR = 0x00;
 
 /* Peripheral Enable */
 /* Repeated write to pe bit is required! */
 I2C0_CR.field.pe = 1;
 I2C0_CR.field.pe = 1;
 
 /* Enable General Call (I2C address 0x00) */
 /* This is not requires by CIS, should we delete it? */
 //[MM]I2C0_CR.field.engc = 1;
 I2C0_CR.field.engc = 0;
 I2C0_CR.field.ack = 1;

 /* Own Address Register*/
 //I2C0_OAR1 = 0;
 I2C0_OAR1 = BL_I2C_SLAVE_ADDRESS;
 /* High bits of Own Address - used for 10 bit addressing */
 I2C0_OAR2.field.add_8_9 = 0;

 //OSAL_isr_install(OSAL_ISR_I2C0_EVENT, 0x0f, i2c_event_isr);
// [RB] use the same handler for both interupt sources
// [RB] This is not an error, see remarks in i2c_event_isr()
 //OSAL_isr_install(OSAL_ISR_I2C0_DATA, 0x0f, i2c_event_isr);
 
 /* wait for I2C bus to be idle (why?) */
 //while(I2C0_SR1.field.busy); [Not More necessary]
 
 isr_addr = (uint32) bl_i2c_event_isr;
 EIC_SIR_9.all =  (isr_addr << 16) | 0x0F;
 EIC_IVR.all =  isr_addr;
 EIC_IER |= BL_EIC_I2C_EVENT_MASK;    ;
 
 isr_addr = (uint32) bl_i2c_xfer_isr;
 EIC_SIR_10.all =  (isr_addr << 16) | 0x0F;
 EIC_IVR.all =  isr_addr;
 EIC_IER |= BL_EIC_I2C_XFER_MASK;    ;
   
 bl->dummy = I2C0_SR1.all;
 
 bl->dummy = I2C0_SR2.all;
 
 for(i = 0; i < 1000; i++)
 {
  if(I2C0_SR1.field.busy == 0)
  {
   break;
  }  
 } 
   
 /* Interrupt Enable */
 I2C0_CR.field.ite = 1;
 BL_I2C_BUSY(); // Program CRQ Line before programming as an output port
 configure_gpio(BL_PORT_B, BL_GPIO_1, BL_GPIO_OUT_OD); // use GPIO_AF_PP for I2C SCL
 
 //configure_gpio(BL_PORT_B, BL_GPIO_2, BL_GPIO_AF_PP); // use GPIO_AF_PP for I2C SCL
 //configure_gpio(BL_PORT_B, BL_GPIO_3, BL_GPIO_AF_PP); // use GPIO_AF_PP for I2C SDA
 // Try to set SCL and SDA at the same time.
 PC0B |= 0x000C;
 PC1B |= 0x000C;
 PC2B |= 0x000C;
 
  /* Set I2C CRQ line to inactive */
 BL_I2C_READY(); // CRQ ON
}

/******************************************************************************/
/* Function:  bl_i2c_if                                                       */
/*                                                                            */
/*! \brief    I2C Boot Loader  
 *  \param    void
 *  \return   void
 *  \remark
 */
/******************************************************************************/

void bl_i2cif(void)
{
  volatile uint32 bl_addr;
  volatile uint32 bl_data;

  if(bl->i2c_flags.msg_rcvd) 
  {
    bl->i2c_flags.msg_rcvd = 0;
    bl->error.all = 0; // Clear all Error Condition Before 
                       // Evaluating The received Message.
    
    if(!bl_i2c_cksum_verify(bl->i2c_irq_rx_buffer))
                           
    {
     // Checksum Error.
     bl->error.field.inv_checksum = 1;
     bl_i2c_ack(bl->error.all);
     return;
    }                       
    
    switch (bl->i2c_irq_rx_buffer[BL_I2C_OP_CODE])
    {

     case BL_I2C_START_ADDRESS:
     
      //MON1_ON(); //Debug
      
      //bl->debug = 0x0001;
     
      bl->start_address = (  (  (   (uint32) bl->i2c_irq_rx_buffer[BL_I2C_MSG_FIRST_BYTE+3]) << 24) +
                            ( ((uint32) bl->i2c_irq_rx_buffer[BL_I2C_MSG_FIRST_BYTE + 2]) << 16) +
                            (((uint32)bl->i2c_irq_rx_buffer[BL_I2C_MSG_FIRST_BYTE + 1]) << 8) +
                             (uint32)bl->i2c_irq_rx_buffer[BL_I2C_MSG_FIRST_BYTE]);
                                                                                                                                 
     
      //bl->error_code = BL_NO_ERROR;
      	                     
                          
      if(bl->start_address == BL_RAM_A_BASE_ADDR)
      {
        // Clear RAM_A area devoted to patch code
        bl->code_size = 0;
        bl->code_checksum = 0;
        bl->max_addr = 0;
        
        bl->ram_ptr = (uint32 *)bl->start_address;
        bl->code_checksum_ptr = &bl->code_checksum;
        bl->code_size_ptr = &bl->code_size;
        bl->max_addr_ptr = &bl->max_addr;
        
        bl_PrepareDram4Dwl(BL_RAM_A_BASE_ADDR, BL_RAM_A_END_ADDR);
        BL_I2C_READY();
      }
      else
      {
       if(bl->start_address >= BL_SDRAM_BASE_ADDR)
       {
        // Code must be downloaded in SDRAM
        bl->sdram_code_size = 0;       	           	
        bl->sdram_code_checksum = 0;	   
        bl->max_sdram_addr = 0;
        
        bl->ram_ptr = (uint32 *)bl->start_address;
        bl->code_checksum_ptr = &bl->sdram_code_checksum;
        bl->code_size_ptr = &bl->sdram_code_size;
        bl->max_addr_ptr = &bl->max_sdram_addr;
        
        if(!bl->dwn_ctrl_flags.patch_code_activated)
        {
         // Patch code (code for RAM_A) must be loaded first than SDRAM code then sdram_init()
   	     // can be patched

   	     bl->dwn_ctrl_flags.patch_code_activated = 1;

         sdram_init(0x40000000);

         // Clear all SDRAM that theoretically can be stored in Serial Flash
         bl_PrepareDram4Dwl(BL_SDRAM_BASE_ADDR, (BL_SDRAM_BASE_ADDR + BL_I2C_SDRAM_SIZE));
        
        }
        BL_I2C_READY();
        //else
        //{
         // Error: Patch Code Not Activated before Download something inside SDRAM
         // Real Error : TBC
        //}
       }
       else
       {        
        // Error: Bad Starting Address
        bl->error.field.bad_starting_address = 1;
       }         
      }
      bl->FlashDownLoadStatus = 1;      
      bl_i2c_ack(bl->error.all);
      //MON1_OFF();
     break; 
     
          
     case BL_I2C_DATA_MSG:       
      //bl->error_code = BL_NO_ERROR;
      
      //bl->debug = 0x0002;
	  if(bl_i2cFillDram())         
      {
       BL_I2C_READY();
      }
             	   
      bl->FlashDownLoadStatus = 2;
      bl_i2c_ack(bl->error.all);
     break;


     case BL_I2C_RUN:   
     
      //bl->debug = 0x0004;    	   
      
      //bl_disable_interrupt();

⌨️ 快捷键说明

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