📄 i2ccore.c
字号:
/* I2cCore.c - MPC8220 PPC I2C Library *//* Copyright 2004 Freescale Semiconductor, Inc. *//*modification history--------------------01c,29jun04,tcl 1.3 removed CR. Added two bytes offset support.01b,19jan04,tcl 1.2 removed i2cMsDelay and sysDecGet. renamed i2cMsDelay back to sysMsDelay01a,19jan04,tcl 1.1 created and seperated from i2c.c*//*DESCRIPTIONThis file contain I2C low level handling library functions*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <vxWorks.h>#include <sysLib.h>#include <iosLib.h>#include <logLib.h>#include <tickLib.h>/* BSP Includes */#include "config.h"#include "mpc8220.h"#include "i2cCore.h"#ifdef DEBUG_I2CCOREint I2CCDbg = 0;#endif#define ABS(x) ((x < 0)? -x : x)char *I2CERR[16] = { "Transfer in Progress\n", /* 0 */ "Transfer complete\n", "Not Addressed\n", /* 2 */ "Addressed as a slave\n", "Bus is Idle\n", /* 4 */ "Bus is busy\n", "Arbitration Lost\n", /* 6 */ "Arbitration on Track\n", "Slave receive, master writing to slave\n", /* 8 */ "Slave transmit, master reading from slave\n", "Interrupt is pending\n", /* 10 */ "Interrupt complete\n", "Acknowledge received\n", /* 12 */ "No acknowledge received\n", "Unknown status\n", /* 14 */ "\n"};/****************************************************************************** * * chk_status - Check I2C status bit * * RETURNS: OK, or ERROR if the bit encounter * */STATUS chk_status (PSI2C pi2c, UINT8 sta_bit, UINT8 truefalse){ int i, status = 0; for (i = 0; i < I2C_POLL_COUNT; i++) { if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0)) return (OK); } I2CCDBG (L2, ("--- sr %x stabit %x truefalse %d\n", pi2c->sr, sta_bit, truefalse, 0, 0, 0)); if (i == I2C_POLL_COUNT) { switch (sta_bit) { case I2C_STA_CF: status = 0; break; case I2C_STA_AAS: status = 2; break; case I2C_STA_BB: status = 4; break; case I2C_STA_AL: status = 6; break; case I2C_STA_SRW: status = 8; break; case I2C_STA_IF: status = 10; break; case I2C_STA_RXAK: status = 12; break; default: status = 14; break; } if (!truefalse) status++; I2CCDBG (NO, ("--- status %d\n", status, 0, 0, 0, 0, 0)); I2CCDBG (NO, (I2CERR[status], 0, 0, 0, 0, 0, 0)); } return (ERROR);}/****************************************************************************** * * I2C Enable - Enable the I2C Controller * */STATUS i2c_enable (SI2C * pi2c, PI2CSET pi2cSet){ int fdr = pi2cSet->bit_rate; UINT8 adr = pi2cSet->i2c_adr; I2CCDBG (L2, ("i2c_enable fdr %d adr %x\n", fdr, adr, 0, 0, 0, 0)); i2c_clear (pi2c); /* Clear FDR, ADR, SR and CR reg */ SetI2cFDR (pi2c, fdr); /* Frequency */ pi2c->adr = adr; pi2c->cr = I2C_CTL_EN; /* Set Enable */ /* The I2C bus should be in Idle state. If the bus is busy, clear the STA bit in control register */ if (chk_status (pi2c, I2C_STA_BB, 0) != OK) { if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA) pi2c->cr &= ~I2C_CTL_STA; /* Check again if it is still busy, return error if found */ if (chk_status (pi2c, I2C_STA_BB, 1) == OK) return ERROR; } return (OK);}/****************************************************************************** * * I2C Disable - Disable the I2C Controller * */STATUS i2c_disable (PSI2C pi2c){ i2c_clear (pi2c); pi2c->cr &= I2C_CTL_EN; /* Disable I2c */ if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA) pi2c->cr &= ~I2C_CTL_STA; if (chk_status (pi2c, I2C_STA_BB, 0) != OK) return ERROR; return (OK);}/****************************************************************************** * * I2C Clear - Clear the I2C Controller * */STATUS i2c_clear (PSI2C pi2c){ pi2c->adr = 0; pi2c->fdr = 0; pi2c->cr = 0; pi2c->sr = 0; return (OK);}STATUS i2c_start (PSI2C pi2c, PI2CSET pi2cSet){#ifdef TWOBYTES UINT16 ByteOffset = pi2cSet->str_adr;#else UINT8 ByteOffset = pi2cSet->str_adr;#endif#if 1 UINT8 tmp = 0;#endif UINT8 Addr = pi2cSet->slv_adr; pi2c->cr |= I2C_CTL_STA; /* Generate start signal */ if (chk_status (pi2c, I2C_STA_BB, 1) != OK) return ERROR; /* Write slave address */ if (i2c_writebyte (pi2c, &Addr) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; }#ifdef TWOBYTES# if 0 /* Issue the offset to start */ if (i2c_write2byte (pi2c, &ByteOffset) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; }#endif tmp = (ByteOffset >> 8) & 0xff; if (i2c_writebyte (pi2c, &tmp) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; } tmp = ByteOffset & 0xff; if (i2c_writebyte (pi2c, &tmp) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; }#else if (i2c_writebyte (pi2c, &ByteOffset) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; }#endif return (OK);}STATUS i2c_stop (PSI2C pi2c){ pi2c->cr &= ~I2C_CTL_STA; /* Generate stop signal */ if (chk_status (pi2c, I2C_STA_BB, 0) != OK) return ERROR; return (OK);}/****************************************************************************** * * Read Len bytes to the location pointed to by *Data from the device * with address Addr. */int i2c_readblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data){ int i = 0; UINT8 Tmp;/* UINT8 ByteOffset = pi2cSet->str_adr; not used? */ UINT8 Addr = pi2cSet->slv_adr; int Length = pi2cSet->xfer_size; I2CCDBG (L1, ("i2c_readblock addr %x data 0x%08x len %d offset %d\n", Addr, (int) Data, Length, ByteOffset, 0, 0)); if (pi2c->sr & I2C_STA_AL) { /* Check if Arbitration lost */ I2CCDBG (FN, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0)); pi2c->sr &= ~I2C_STA_AL; /* Clear Arbitration status bit */ return ERROR; } pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ if (i2c_start (pi2c, pi2cSet) == ERROR) return ERROR; pi2c->cr |= I2C_CTL_RSTA; /* Repeat Start */ Tmp = Addr | 1; if (i2c_writebyte (pi2c, &Tmp) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; } if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01)) return ERROR; pi2c->cr &= ~I2C_CTL_TX; /* Set receive mode */ if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01)) return ERROR; /* Dummy Read */ if (i2c_readbyte (pi2c, &Tmp, &i) != OK) { i2c_stop (pi2c); /* Disable I2c */ return ERROR; } i = 0; while (Length) { if (Length == 2) pi2c->cr |= I2C_CTL_TXAK; if (Length == 1) pi2c->cr &= ~I2C_CTL_STA; if (i2c_readbyte (pi2c, Data, &Length) != OK) { return i2c_stop (pi2c); } i++; Length--; Data++; } if (i2c_stop (pi2c) == ERROR) return ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -