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

📄 bli2c.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      EIC_ICR.field.irq_en = 0;

      // In case of no SDRAM patch file,  SDRAM must be initialized
      // In case of SDRAM patch files, SDRAM has been already initilaized.
      if(!bl->dwn_ctrl_flags.patch_code_activated)
      {
        sdram_init(0x40000000);                           
      }

      // Jump to ROM Code Entry Point
      //MON1_OFF();
      Reset_Handler(0x40000000);
       	   
	  //bl->FlashDownLoadStatus = 3;
	 break;
	 
	 case BL_I2C_RUN_ROM_CODE:
     // Just go to the Mask ROM S/W.   
     //bl->debug = 0x0008;
      bl_copy_jt();

      sdram_init(0x40000000);

      // Disable Interrupt
      EIC_ICR.field.irq_en = 0;
      Reset_Handler(0x40000000);
	 break;
	 
	 
	 case BL_I2C_INFO:
	  //MON1_OFF(); Debug
	  //bl->debug = 0x0010;
	  switch(bl->i2c_irq_rx_buffer[2])
	  {
	   case BL_RAM_A_INFO:
	    bl->i2c_irq_tx_buffer[0] = BL_RAM_A_INFO_LEN;
 
        bl->i2c_irq_tx_buffer[1] = (uint8) bl->code_checksum;
        bl->i2c_irq_tx_buffer[2] = (uint8) (bl->code_checksum >> 8);
        bl->i2c_irq_tx_buffer[3] = (uint8) (bl->code_checksum >> 16);
        bl->i2c_irq_tx_buffer[4] = (uint8) (bl->code_checksum >> 24);
 
        bl->i2c_irq_tx_buffer[5] = (uint8) bl->code_size;
        bl->i2c_irq_tx_buffer[6] = (uint8) (bl->code_size >> 8);
        bl->i2c_irq_tx_buffer[7] = (uint8) (bl->code_size >> 16);
        bl->i2c_irq_tx_buffer[8] = (uint8) (bl->code_size >> 24);
 
        bl->i2c_irq_tx_buffer[9] = (uint8) bl->max_addr;
        bl->i2c_irq_tx_buffer[10] = (uint8) (bl->max_addr >> 8);
        bl->i2c_irq_tx_buffer[11] = (uint8) (bl->max_addr>> 16);
        bl->i2c_irq_tx_buffer[12] = (uint8) (bl->max_addr >> 24);
 
        bl->i2c_irq_tx_buffer[13] = bl_i2c_cksum(bl->i2c_irq_tx_buffer);
        BL_I2C_READY();
 
	   break;
	   
	   case BL_SDRAM_INFO:
	    bl->i2c_irq_tx_buffer[0] = BL_SDRAM_INFO_LEN;
 
        bl->i2c_irq_tx_buffer[1] = (uint8) bl->sdram_code_checksum;
        bl->i2c_irq_tx_buffer[2] = (uint8) (bl->sdram_code_checksum >> 8);
        bl->i2c_irq_tx_buffer[3] = (uint8) (bl->sdram_code_checksum >> 16);
        bl->i2c_irq_tx_buffer[4] = (uint8) (bl->sdram_code_checksum >> 24);
 
        bl->i2c_irq_tx_buffer[5] = (uint8) bl->sdram_code_size;
        bl->i2c_irq_tx_buffer[6] = (uint8) (bl->sdram_code_size >> 8);
        bl->i2c_irq_tx_buffer[7] = (uint8) (bl->sdram_code_size >> 16);
        bl->i2c_irq_tx_buffer[8] = (uint8) (bl->sdram_code_size >> 24);
 
        bl->i2c_irq_tx_buffer[9] = (uint8) bl->max_sdram_addr;
        bl->i2c_irq_tx_buffer[10] = (uint8) (bl->max_sdram_addr >> 8);
        bl->i2c_irq_tx_buffer[11] = (uint8) (bl->max_sdram_addr>> 16);
        bl->i2c_irq_tx_buffer[12] = (uint8) (bl->max_sdram_addr >> 24);
 
        bl->i2c_irq_tx_buffer[13] = bl_i2c_cksum(bl->i2c_irq_tx_buffer);
        BL_I2C_READY();

	   break;
	   
	   default:	     
	     bl->error.field.inv_param = 1;
	     bl_i2c_ack(bl->error.all);
	   break;
	  }
	  
	 break;
	 
	 case BL_I2C_XFER_ON:
	  //bl->debug = 0x0020;
	  bl->dwn_ctrl_flags.continous_xfer = 1;
	  bl->code_data_byte_idx = 0;
	  bl_i2c_ack(bl->error.all);
	  BL_I2C_READY();
	 break;
	 
	 case BL_I2C_XFER_OFF:
	  //bl->debug = 0x0040;
	  bl->dwn_ctrl_flags.continous_xfer = 0;
	  bl_i2c_ack(bl->error.all);
	  BL_I2C_READY();
	 break;
	 
	 case BL_I2C_EMERGENCY_INIT:
	  emergency_i2c_init();
	  bl_i2c_ack(bl->error.all);
	  BL_I2C_READY();
	 break;

     default:
       //bl->debug = 0x0080;
       bl->error.field.inv_op_code = 1;
       bl_i2c_ack(bl->error.all);
     break;
   }   	  
  } //if(bl->i2c_flags.msg_rcvd)    
}

/******************************************************************************/
/* Function:  bl_i2c_cksum_verify                                             */
/*                                                                            */
/*! \brief    Verify the Checksum of the Received Message 
 *  \param    Pointer to the First Byte of the Received Message
 *  \return   1-> Cksum OK 0-> Cksum Error
 *  \remark
 */
/******************************************************************************/
uint8 bl_i2c_cksum_verify(uint8 * msg_ptr)
{
  uint8  cksum;
  uint16 i;
  uint16 len;
  
  cksum = 0x5A;
  len = msg_ptr[0];
  
  for(i = 1; i < len; i++)
  {
   cksum+= msg_ptr[i];
  }
  
  if(cksum == msg_ptr[len])
  {
   return 1; //Ok
  }
  else
  {
   return 0; //Fails
  }
}

/******************************************************************************/
/* Function:  bl_i2cFillDram                                                  */
/*                                                                            */
/*! \brief    Write RAM_A and SDRAM with Patched Code 
 *  \param    None
 *  \return   1-> OK 0-> Error Condition
 *  \remark
 */
/******************************************************************************/
uint32 bl_i2cFillDram(void)
{
  uint32 i,len;

  uint32 * bl_ram_addr_ptr;
  uint32 bl_ram_addr;

  if(bl->start_address >= BL_SDRAM_BASE_ADDR)
  { 
   bl_ram_addr = (bl->start_address + bl->sdram_code_size);
   bl_ram_addr_ptr = (uint32 *) (bl_ram_addr);
  }
  else
  {
   
   bl_ram_addr = (bl->start_address + bl->code_size); 
   bl_ram_addr_ptr = (uint32 *)bl_ram_addr;
  } 

  //len = (bl_rx_buffer[0] & 0xFF);
  //The lenght must be multiple of 4.
  len = bl->i2c_irq_rx_buffer[BL_I2C_MSG_LEN];
  len -= 2;
  if(len % 4)
  {
   bl->error.field.bad_len = 1;
   return 0;
  }
  
  i = BL_I2C_MSG_FIRST_BYTE;
  
  while(i < len)
  {
    bl->code_word.field.b0 = bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b1 = bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b2 = bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b3 = bl->i2c_irq_rx_buffer[i++];
    *bl_ram_addr_ptr++ = bl->code_word.all;
    if((uint32)bl_ram_addr_ptr < BL_SDRAM_BASE_ADDR)
    {
     bl->code_size+=4; // code Size in Bytes
     bl->code_checksum += bl->code_word.all;
     bl->max_addr = (uint32) bl_ram_addr_ptr;
    } 
    else
    {
     bl->sdram_code_size+=4;
     bl->max_sdram_addr = (uint32) bl_ram_addr_ptr;
     bl->sdram_code_checksum += bl->code_word.all;
    }    
  }
      
  // Verify

  bl_ram_addr_ptr = (uint32 *) (bl_ram_addr);

  i = BL_I2C_MSG_FIRST_BYTE;
  
  while(i < len)
  {
    bl->code_word.field.b0 =  bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b1 =  bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b2 =  bl->i2c_irq_rx_buffer[i++];
    bl->code_word.field.b3 =  bl->i2c_irq_rx_buffer[i++];
    if(bl->code_word.all != *bl_ram_addr_ptr)
    {
     bl->error.field.ram_verify = 1;
     return 0; // Fail
    }
    bl_ram_addr_ptr++;
  }

  return 1; // Ok
}

/******************************************************************************/
/* Function:  bl_i2c_ack                                                      */
/*                                                                            */
/*! \brief    Prepeare the ACK message for each Received I2C Message 
 *  \param    Error Byte (Err = 0 -> No Error)
 *  \return   None
 *  \remark
 */
/******************************************************************************/
void bl_i2c_ack(uint8 err)
{
 bl->i2c_irq_tx_buffer[0] = BL_I2C_ACK_LEN;
 bl->i2c_irq_tx_buffer[1] = err;
 bl->i2c_irq_tx_buffer[2] = bl_i2c_cksum(bl->i2c_irq_tx_buffer);
 
}

/******************************************************************************/
/* Function:  bl_i2c_cksum                                                      */
/*                                                                            */
/*! \brief    Calculate the Checksum for Tx I2C Message 
 *  \param    Pointer to the first byte of the message to be Tx
 *  \return   Checksum
 *  \remark
 */
/******************************************************************************/
uint8 bl_i2c_cksum(uint8 * msg_ptr)
{
 uint16 i;
 uint8  cksum;
 
 cksum = 0x5A;
 
 for(i = 1; i < msg_ptr[0]; i++)
 {
  cksum+= msg_ptr[i];
 }
 return cksum;
}


void emergency_i2c_init(void)
{
 uint32 i;
 
 
 EIC_ICR.field.irq_en = 0; 
 
 // Set SCL and SDA as input
 PC0B |= 0x000C;
 PC1B &= 0xFFF3;
 PC2B &= 0xFFF3;
 
 SAB_PUR0.field.i2c = 0;    // Bit 13  0x2000
 //SAB_PCG0.field.i2c = 0;    // Bit 13  0x2000
 for(i = 0; i < 100; i++);
 //SAB_PCG0.field.i2c = 1;    // Bit 13  0x2000
 SAB_PUR0.field.i2c = 1;    // Bit 13  0x2000
 
 
 
 I2C0_CR.all = 0;

 /* Configure Frequency Bits to match I2C setup/hold times */
 I2C0_OAR2.field.fr = (bl->i2c_irq_rx_buffer[2] & 0x07);   // 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 = bl->i2c_irq_rx_buffer[3] >> 7; 
 I2C0_CCR.field.cc_0_6 = bl->i2c_irq_rx_buffer[3] & 0x7F;
  

 /* Extended Clock Control Register */
 /* set the clock divider along with I2C_CCR register */
 I2C0_ECCR = bl->i2c_irq_rx_buffer[4];
 
 /* Peripheral Enable */
 /* Repeated write to pe bit is required! */
 I2C0_CR.field.pe = 1;
 I2C0_CR.field.pe = 1;
 
 
 I2C0_CR.field.engc  = bl->i2c_irq_rx_buffer[5] & 0x01;
 
 I2C0_CR.field.ack = 1;

 /* Own Address Register*/
 //I2C0_OAR1 = 0;
 I2C0_OAR1 = bl->i2c_irq_rx_buffer[6];
 /* 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?) */
 
 
 //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;    ;
 
 /* Interrupt Enable */
 bl->dummy = I2C0_SR1.all;
 bl->dummy = I2C0_SR2.all;
 for(i=0; i<1000; i++)
 {
  if(I2C0_SR1.field.busy == 0)
  {
   break;
  }
 } 
 
 I2C0_CR.field.ite = 1;
 // Set SCL and SDA as alternate function
 PC0B |= 0x000C;
 PC1B |= 0x000C;
 PC2B |= 0x000C;
 
 for(i=0; i<0x10000; i++); // This is a good value
 EIC_ICR.field.irq_en = 1; 
 
  /* Set I2C CRQ line to inactive */
 //BL_I2C_READY(); // CRQ ON
}

⌨️ 快捷键说明

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