有关TEF6621编写驱动的流程
各位大侠,本人以前从来没有写过I2C 的驱动,最近工作要写一个 mid上收音机的驱动,所有功能都是通过I2C 来完成。请求高手们给我指点一下 编写I2C 驱动的流程,最好详细一些。呵呵。。。 谢谢了!
[解决办法]
编写的流程就简单了,到网上看下I2C的原理就行了。我写过6621的I2C驱动,感觉你按照这个流程就比较清晰了,个别芯片可能对读要求的顺序有点区别,比如24c08 eeprom读的时候要先发送写命令再写子地址。
直接给你贴上我的6621 I2C驱动吧。
/*------------------------------------------
- Name: tunerRegSend
- DESCRIPTION: -
-
- modification history
- --------------------
- 11:26am, 29.Sep.2010, modified by Sirius
* --------------------
------------------------------------------*/
void tunerRegSend(unsigned char start, unsigned char end)
{
unsigned char i, num;
num = (unsigned char)(end - start + 1);
for (i = 0; i < 3; i++) {
if (I2cWriteWithoutSubaddr(I2C_TUNER_ADR, &Radio.TunerBuff[start], num)==I2C_NORMAL) {
break;
}
i2cErr.tunerRegI2cWrErr++;
}
}
/*------------------------------------------
- Name: tunerRegRead
- DESCRIPTION: -
-
- modification history
- --------------------
- 11:27am, 29.Sep.2010, modified by Sirius
* --------------------
------------------------------------------*/
void tunerRegRead(void)
{
unsigned char i;
for (i = 0; i < 3; i++) {
if (I2cReadWithoutSubaddr(I2C_TUNER_ADR,&Radio.ReadBuff[0].byte,5) == I2C_NORMAL) {
break;
}
i2cErr.tunerRegI2cRdErr++;
}
}
/*=======================================================
- Name: I2cWriteWithoutSubaddr
- DESCRIPTION: - Tx nbytes data to slave without subaddress.
-
- Input:
- Output:
-
- modification history
- --------------------
- 17:01pm, 21.Nov.2009, written by Sirius
* --------------------
=======================================================*/
u8 I2cWriteWithoutSubaddr(u8 addr, u8 *data, u8 nbyte)
{
u8 err;
u8 stat;
//OSSemPend(I2cSem, 0, &err);
I2cAckCfg(I2C_ACK_CURR); /* Ack on current byte */
err = I2C_NORMAL;
stat = 0;
switch (stat) {
case 0: /* Generate start condition */
I2cGerStart();
if (I2cEveChk(I2C_EVENT_MASTER_START_SENT) == FALSE) {
err = I2C_STA_ERR;
break;
}
stat = 1;
case 1: /* Write device address */
I2cSend7bitAddr(addr, I2C_DIRECTION_TX);
if (I2cEveChk(I2C_EVENT_MASTER_ADDRESS_ACKED) == FALSE) {
err = I2C_ADDR_ACK_ERR;
break;
}
I2cClrFlag(I2C_FLAG_ADDRESSSENTMATCHED);
stat = 2;
case 2: /* Write data buffer to device */
while (nbyte--) {
I2cSendData(*data++);
if (I2cEveChk(I2C_EVENT_MASTER_BYTE_TRANSMITTED) == FALSE) {
err = I2C_WRITE_ERR;
break;
}
}
break;
default: break;
}
I2cGerStop(); /* Generate stop condition */
if (err != I2C_NORMAL) {
I2cReset(); /* Reset I2c if error occured */
//OSQPost(MstarMsgQueue, MST_MSG_FAC_TEST, TEST_VAR);
}
I2cDelay();
//OSSemPost(I2cSem);
return (err);
}
/*=======================================================
- Name: I2cRead
- DESCRIPTION: - Read n bytes data from slave device.
-
- Input: 'addr' is device main I2C address. 'buff' is the pointer to buffer for
saving received data. 'nbyte' is the number of bytes to read.
- Output: error type during write process.
-
- modification history
- --------------------
- 17:02pm, 21.Nov.2009, written by Sirius
* --------------------
=======================================================*/
u8 I2cReadWithoutSubaddr(u8 addr, u8 *buff, u8 nbyte)
{
u8 err;
u8 stat;
u8 i;
//OSSemPend(I2cSem, 0, &err);
I2cAckCfg(I2C_ACK_CURR); /* Ack on current byte */
err = I2C_NORMAL;
stat = 0;
switch (stat) {
case 0: /* Generate start condition */
I2cGerStart();
if (I2cEveChk(I2C_EVENT_MASTER_START_SENT) == FALSE) {
err = I2C_STA_ERR;
break;
}
stat = 1;
case 1: /* Write device address */
if (nbyte == 1) { /* Need to stop ACK before reading only one data */
I2cAckCfg(I2C_ACK_NONE);
}
I2cSend7bitAddr(addr, I2C_DIRECTION_RX);
if (I2cEveChk(I2C_EVENT_MASTER_ADDRESS_ACKED) == FALSE) {
err = I2C_ADDR_ACK_ERR;
break;
}
I2cClrFlag(I2C_FLAG_ADDRESSSENTMATCHED);
stat = 2;
case 2: /* Read first (nbyte-1) bytes data */
for(i = 0; i < (u8)(nbyte - 1); i++) {
if (I2cEveChk(I2C_EVENT_MASTER_BYTE_RECEIVED) == FALSE) {
err = I2C_READ_ERR;
break;
}
*(buff + i) = I2cReceiveData();
}
stat = 3;
case 3: /* Read last byte of data */
I2cAckCfg(I2C_ACK_NONE);/* Need to stop ACK for last byte to read */
if (I2cEveChk(I2C_EVENT_MASTER_BYTE_RECEIVED) == FALSE) {
err = I2C_READ_ERR;
break;
}
*(buff + i) = I2cReceiveData();
break;
default: break;
}
I2cGerStop(); /* Generate stop condition */
if (err != I2C_NORMAL) {
I2cReset(); /* Reset I2c if error occured */
//OSQPost(MstarMsgQueue, MST_MSG_FAC_TEST, TEST_VAR);
}
I2cDelay();
//OSSemPost(I2cSem);
return (err);
}