📄 i2c_sbl.c
字号:
/*****************************************************************************
* i2c_sbl.c: I2C_SBL API file for NXP LPC210x Family Microprocessors
*
* Copyright(C) 2006, NXP Semiconductor
* All rights reserved.
*
* History
* 2005.10.01 ver 1.00 Prelimnary version, first Release
******************************************************************************/
#include "LPC210x.H"
#include "i2c_sbl.h"
#include "i2c.h"
extern unsigned int data_block_cnt;
/*****************************************************************************
** Function name: i2c_sbl_init
** Description: This function initializes the I2C data and clock bus
** Parameter: None
** Returned value: None
*****************************************************************************/
void i2c_sbl_init(void)
{
PINSEL0 |= 0x00000050; // Set P0.2 as SCL0 and P0.3 as SDA0
/*--- Clear flags ---*/
I2C0CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
I2C0SCLL = I2SCLL_SCLL;
I2C0SCLH = I2SCLH_SCLH;
I2C0ADR = I2CSL_ADDRS << 1;
I2C0CONSET = I2CONSET_I2EN | I2CONSET_AA;
} // i2c_sbl_init
/*****************************************************************************
** Function name: i2c0_readbyte
** Description: This function reads data from the I2C data register
** Parameter: None
** Returned value: I2C data byte
*****************************************************************************/
unsigned char i2c0_readbyte(void)
{
unsigned char databyte;
while( !(I2C0CONSET & I2CONSET_SI) );
while( (!(I2C0STAT & 0x80)) && (!(I2C0STAT & 0x90)) );
databyte = I2C0DAT; // read data
I2C0CONCLR = I2CONSET_SI;
return (databyte);
} // i2c0_readbyte
/*****************************************************************************
** Function name: i2c0_writebyte
** Description: This function writes data to the I2C data register
** Parameter: I2C data byte
** Returned value: None
*****************************************************************************/
void i2c0_writebyte(unsigned char databyte)
{
while( !(I2C0CONSET & I2CONSET_SI) );
while ((!(I2C0STAT & 0xA8))&&(!(I2C0STAT & 0xB8))&&(!(I2C0STAT & 0xC8)));
I2C0DAT = databyte; // write data
I2C0CONCLR = I2CONSET_SI;
return;
} // i2c0_writebyte
/*****************************************************************************
** Function name: i2c0_ready
** Description: This function enables I2C interface and setup ACK to
** return acknowledge when the address in the Slave Address
** register has been received.
** Parameter: None
** Returned value: None
*****************************************************************************/
void i2c0_ready(void)
{
I2C0ADR = I2CSL_ADDRS << 1;
I2C0CONSET = (I2CONSET_I2EN | I2CONSET_AA);
} // i2c0_ready
/*****************************************************************************
** Function name: slave_receive
** Description: The order of the slave receive is:
** 1. I2C Slave Device Addr: 0x2E
** 2. Command ID: 0x02
** 3. Block number (MSB)
** 4. Block number (LSB)
**
** If both MSB and LSB of block numbers are zero, get the
** checksum. Otherwise, get 1024 bytes of data.
** Parameter: I2C slave buffer
** Returned value: status of slave_receive
*****************************************************************************/
unsigned int slave_receive( unsigned char slave_buffer[] )
{
unsigned char cmdbyte, paraMSB, paraLSB, databyte, checksumbyte;
unsigned char checksum = 0;
unsigned int i;
i2c_sbl_init();
i2c0_ready();
while( !(I2C0CONSET & I2CONSET_SI) );
// neither I2C Read bit set, nor arbitration loss, start of slave receive
while(((I2C0STAT & 0x60)==0)&&((I2C0STAT & 0x68)==0));
I2C0CONSET = I2CONSET_AA; // Return ACK on first byte
I2C0CONCLR = I2CONSET_SI;
/* 2. Command ID handling */
cmdbyte = i2c0_readbyte();
checksum -= cmdbyte;
if( cmdbyte == 0x02 ) // Command byte
{
I2C0CONSET = I2CONSET_AA; // Return ACK on DATA byte
}
else
{
/* This case is not handled in main(), please take note */
I2C0CONCLR = I2CONSET_AA; // BAD command, return NACK on DATA byte
return( COMMAND_BAD );
}
/* 3. Block number (MSB) */
paraMSB = i2c0_readbyte(); // Read data
checksum -= paraMSB;
I2C0CONSET = I2CONSET_AA; // Return ACK on DATA byte
/* 4. Block number (LSB) */
paraLSB = i2c0_readbyte(); // Read data
checksum -= paraLSB;
if( paraMSB == 0x00 && paraLSB == 0x00 )
{
checksumbyte = i2c0_readbyte(); // Receive checksum data
if( checksum != checksumbyte ) // Check checksum of command ID and block number (MSB & LSB)
{
I2C0CONCLR = I2CONSET_AA; // Return NACK on data byte
return CHECKSUM_BAD;
}
I2C0CONSET = I2CONSET_AA; // Return ACK on data byte
return( DONE );
}
else
{
I2C0CONSET = I2CONSET_AA; // Return ACK on data byte
}
/* Save global varaible for block number */
data_block_cnt = (paraMSB << 8) | paraLSB;
for(i = 0; i < 1024; i++)
{
while( !(I2C0CONSET & I2CONSET_SI) );
if( (I2C0STAT == 0xA0) && (i<1023) ) // STOP occurs before completion
{
I2C0CONCLR = I2CONSET_SI;
I2C0CONCLR = I2CONSET_AA; // Return NACK on data byte
return( DATA_BAD );
}
else
{
databyte = i2c0_readbyte(); // Receive data from the I2C data register
slave_buffer[i] = databyte; // Store data in slave buffer
checksum -= databyte; // Add data to the checksum
I2C0CONSET = I2CONSET_AA; // Return ACK on data byte
}
}
checksumbyte = i2c0_readbyte(); // Receive checksum data
if (checksum != checksumbyte) // Check checksum of command ID, block number (MSB and LSB) and received data
{
I2C0CONCLR = I2CONSET_AA; // Return NACK on data byte
return CHECKSUM_BAD;
}
I2C0CONSET = I2CONSET_AA; // Return ACK on data byte
return(DATA_OK);
} // slave_receive
/*****************************************************************************
** Function name: slave_transmit
** Description: The function sends thrice the status of the SBL:
** '0x00' - Programming success
** '0xFF' - Programming failure
** Parameter: SBL status byte
** Returned value: None
*****************************************************************************/
void slave_transmit( unsigned char statusbyte )
{
I2C0CONCLR = I2CONSET_SI;
i2c0_ready();
i2c0_writebyte(statusbyte);
I2C0CONSET = I2CONSET_AA;
i2c0_writebyte(statusbyte);
I2C0CONSET = I2CONSET_AA;
i2c0_writebyte(statusbyte);
I2C0CONCLR = I2CONSET_AA;
return;
} // slave_transmit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -