📄 bli2c.c
字号:
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 + -