📄 lib_i2c.c
字号:
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CTxClearSCL (I2Cdesc *I2C_pt)
//* Object : Clear SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CTxClearSCL (I2Cdesc *I2C_pt)
{//* Begin
I2C_pt->pioa_base->PIO_CODR = I2C_pt->SCL_line; //* Clear SCL line
if(I2C_pt->countBit == 0)
//* set SDA line as an input
I2C_pt->pioa_base->PIO_ODR = I2C_pt->SDA_line;
//* change interrupt handler to at91_I2CTxSendBit
I2C_pt->I2CTCHandler = at91_I2CTxSendBit;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CRxSetSCL (I2Cdesc *I2C_pt)
//* Object : set SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CRxSetSCL (I2Cdesc *I2C_pt)
{//* Begin
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
//* change interrupt handler to at91_I2CRxReceiveBit
I2C_pt->I2CTCHandler = at91_I2CRxReceiveBit;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CRxClearSCL (I2Cdesc *I2C_pt)
//* Object : Clear SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CRxClearSCL (I2Cdesc *I2C_pt)
{//* Begin
I2C_pt->pioa_base->PIO_CODR = I2C_pt->SCL_line; //* Clear SCL line
if(I2C_pt->countBit == 0)
{
//* change interrupt handler to at91_I2CI2CRxPrepareACK
I2C_pt->I2CTCHandler = at91_I2CRxPrepareACK;
I2C_pt->pioa_base->PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
if(I2C_pt->nbI2CByte == 0) //* If last byte
{
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SDA_line; //* set SDA line for NACK
}
else
{
I2C_pt->pioa_base->PIO_CODR = I2C_pt->SDA_line; //* clear SDA line for ACK
} //* End if last Byte
}//* End countBit
else
//* change interrupt handler to at91_I2CRx
I2C_pt->I2CTCHandler = at91_I2CRxReceiveBit;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CRxReceiveByte (I2Cdesc *I2C_pt)
//* Object : clear SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CRxReceiveByte (I2Cdesc *I2C_pt)
{//* Begin
I2C_pt->pioa_base->PIO_ODR = I2C_pt->SDA_line; //* set SDA line as an input
I2C_pt->pioa_base->PIO_CODR = I2C_pt->SCL_line; //* clear SCL line
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nbI2CByte--; //* decrement byte
if(I2C_pt->nbI2CByte == 0)
I2C_pt->mode = STOP; //* next mode
//* change interrupt handler to at91_I2C
I2C_pt->I2CTCHandler = at91_I2CRxReceiveBit;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : u_char at91_I2CRxReceiveBit (I2Cdesc *I2C_pt)
//* Object : set SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CRxReceiveBit (I2Cdesc *I2C_pt)
{//* Begin
u_char bit_val;
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
I2C_pt->countBit--; //* decrement countBit
//* get bit
if((I2C_pt->pioa_base->PIO_PDSR & I2C_pt->SDA_line) == I2C_pt->SDA_line)
bit_val = 1;
else
bit_val = 0;
//* if bit counter > 0
if(I2C_pt->countBit > 0)
//* update working byte
*I2C_pt->RxEnd |= (bit_val << I2C_pt->countBit);
else
*(I2C_pt->RxEnd++) |= (bit_val << I2C_pt->countBit) ;
//* change interrupt handler to at91_I2CRxClearSCL
I2C_pt->I2CTCHandler = at91_I2CRxClearSCL;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CWait (I2Cdesc *I2C_pt)
//* Object : Waite Handler
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CWait (I2Cdesc *I2C_pt)
{//* Begin
I2C_pt->countBit--; //* decrement countBit for time
if(I2C_pt->countBit == 0) //* if bit counter = 0
{
I2C_pt->timerBase->TC_CCR = TC_CLKDIS ;
at91_I2C_lineOpen(I2C_pt,I2C_pt->timerMem);
}
}//* End
//*-----------------------------------------------------------------------------
//* Export function prototype
//*-----------------------------------------------------------------------------
//*-----------------------------------------------------------------------------
//* Function Name : u_char at91_I2CRxReceiveBit (I2Cdesc *I2C_pt)
//* Object : C Interrupt Handler called by assembly handler
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void I2C_lineHandlerInt (I2Cdesc *I2C_pt)
{//* Begin
u_char dummy;
//* acknowledge interrupt status
dummy = I2C_pt->timerBase->TC_SR;
//* call automate state handler*/
(*(I2C_pt->I2CTCHandler))(I2C_pt);
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : (I2Cdesc *I2C_pt)
//* Object : Open I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* RCValue Timer value for gererate I2C SCL alf periode
//* RCValue = ( (MCKI / 2) /2 ) * SCL
//* TCCLKS =0
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2C_lineOpen (I2Cdesc *I2C_pt, u_int RCValue)
{//* Begin
//* line
I2C_pt->state = OK;
I2C_pt->pioa_base->PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SDA_line; //* set SDA line
I2C_pt->pioa_base->PIO_OER = I2C_pt->SCL_line; //* set SCL line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
at91_clock_open(I2C_pt->pio_ctrl_desc->periph_id);
//* TIMER configuration
//* Set the mode of the timer
//* Open the clock of the timer
at91_clock_open(I2C_pt->channelId);
//* 0x0000C 4 0 0
//* 1100 01 00 0 0 00 0 000
//* MCK/2
//* CLKI: 0 = Counter is incremented on rising edge of the clock.
//* BURST: The clock is not gated by an external signal.
//* CPCSTOP: Counter clock is not stopped when counter reaches RC.
//* CPCDIS:Counter clock is not disabled when counter reaches RC.
//* EEVTEDG:0 1 XC0 Output
//* ENETRG:The external event resets the counter and starts the counter clock.
//*
//* CPCTRG:RC Compare resets the counter and starts the counter clock.
//* WAVE = 1
I2C_pt->timerBase->TC_CMR = 0x0000C400;
//* Set timer
I2C_pt->timerBase->TC_RC = RCValue; //*
I2C_pt->timerMem = RCValue; //* Save Timer value
//* modificationn set in LEVEL not EDGE
at91_irq_open(I2C_pt->channelId, 7, AIC_SRCTYPE_INT_LEVEL_SENSITIVE, I2C_pt->AICHandler);
//* Enable the clock
I2C_pt->timerBase->TC_CCR = TC_CLKEN;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : I2C_lineClose(I2Cdesc *I2C_pt)
//* Object : Close I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2C_lineClose (I2Cdesc *I2C_pt)
{//* Begin
//* Sate
I2C_pt->state = OK;
//* set line
I2C_pt->pioa_base->PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SDA_line; //* set SDA line
I2C_pt->pioa_base->PIO_OER = I2C_pt->SCL_line; //* set SCL line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
//* change interrupt handler to
I2C_pt->I2CTCHandler = no_handler_tc;
at91_clock_close(I2C_pt->pio_ctrl_desc->periph_id);
//* TIMER configuration
at91_clock_close(I2C_pt->channelId);
//* Disable the clock and interrupts
I2C_pt->timerBase->TC_CCR = TC_CLKDIS ;
I2C_pt->timerBase->TC_IDR = 0xFFFFFFFF ;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CWrite (I2Cdesc *I2C_pt, u_short loadAddress, u_char nbByte)
//* Object : I2C Write Byte & Write Page
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* : loadAddress Address on slave
//* : nbByte Write to bytes
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CWrite (I2Cdesc *I2C_pt, u_short loadAddress, u_int nbByte )
{//* Begin
//* initialize state
I2C_pt->state = NOK;
I2C_pt->pioa_base->PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
I2C_pt->pioa_base->PIO_OER = I2C_pt->SCL_line; //* set SCL line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SDA_line; //* set SDA line
//* get byte to transmit
I2C_pt->I2CByte = I2C_pt->deviceAddress | WRITE_BIT ;
I2C_pt->loadAddress = loadAddress; //* get address in Target
I2C_pt->nbI2CByte = nbByte; //* get nb byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* Send Write
I2C_pt->mode = HIGH_ADDRESS_WRITE; //* next mode
//* change interrupt handler to at91_I2CSendStartSDA
I2C_pt->I2CTCHandler = at91_I2CSendStartSDA;
//* Enable RC compare interrupt
I2C_pt->timerBase->TC_IER = TC_CPCS;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CRead (I2Cdesc *I2C_pt, u_short loadAddress, u_char nbByte)
//* Object : I2C RANDOM Read & Sequential Read
//* I2C sequence:
//* start addI2C W ACK loadAddressMSD ACK loadAddressLSB ACK Start addI2C R data NACK stop
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* : loadAddress address of return buffer
//* : nbByte
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void at91_I2CRead (I2Cdesc *I2C_pt, u_short loadAddress, u_int nbByte )
{//* Begin
u_int loop;
//* clean the rx buff for shifting byte
for(loop = 0; loop < nbByte ; loop++)
{
I2C_pt->RxPtr[loop]=0;
}
//* initialize state
I2C_pt->state = NOK;
I2C_pt->pioa_base->PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
I2C_pt->pioa_base->PIO_OER = I2C_pt->SCL_line; //* set SCL line as an output
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SCL_line; //* set SCL line
I2C_pt->pioa_base->PIO_SODR = I2C_pt->SDA_line; //* set SDA line
//* get byte to read
I2C_pt->I2CByte = I2C_pt->deviceAddress | WRITE_BIT;
I2C_pt->loadAddress = loadAddress; //* get address
I2C_pt->nbI2CByte = nbByte; //* get nb byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* next mode
I2C_pt->mode = HIGH_ADDRESS_READ;
//* change interrupt handler to at91_I2CSendStartSDA
I2C_pt->I2CTCHandler = at91_I2CSendStartSDA;
//* Enable RC compare interrupt
I2C_pt->timerBase->TC_IER = TC_CPCS;
}//* End
//*-----------------------------------------------------------------------------
//* Function Name : at91_I2CWaitTime
//* Object : I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* loadAddress - Address on slave
//* nbByte - Read to bytes
//* I2C_address - I2C address Divice
//* mcki - MCKI freq in KHz
//* Output Parameters : FALSE if input parameter are out of range
//*-----------------------------------------------------------------------------
u_int at91_I2CWaitTime (I2Cdesc *I2C_pt,u_int time,u_int mcki)
{//* Begin
while(I2C_pt->state != OK);
//* load timer value for 0,2 ms
mcki = mcki/2;
//* check input value
if ((mcki <= 0x0FFFF ) & ((time ) < 128))
{
I2C_pt->timerBase->TC_RC = mcki; /* work in step of 1 ms */
//* initialize state
I2C_pt->state = NOK;
//* initialize countBit time
I2C_pt->countBit = time ;
//* change interrupt handler to at91_I2CWait
I2C_pt->I2CTCHandler = at91_I2CWait;
//* load timer value for 1 ms
I2C_pt->timerBase->TC_RC = mcki;
//* Enable RC compare interrupt
I2C_pt->timerBase->TC_IER = TC_CPCS;
//* Trig the timer
I2C_pt->timerBase->TC_CCR = TC_SWTRG;
}
else
{
return (FALSE);
}
return (TRUE);
}//* End
//*---------------------------------------------------------------------------------------
//* Function Name : at91_I2CTransfertEnd(I2Cdesc *I2C_pt)
//* Object : Wait the end I2C transfert when I2C_line.state != OK
//* Input Parameters : None
//* Output Parameters : none
//*---------------------------------------------------------------------------------------
void at91_I2CTransfertEnd(I2Cdesc *I2C_pt)
{//* Begin
while(I2C_pt->state != OK);
}//* End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -