diff options
Diffstat (limited to 'cpu/mpc8220/i2cCore.c')
-rw-r--r-- | cpu/mpc8220/i2cCore.c | 627 |
1 files changed, 0 insertions, 627 deletions
diff --git a/cpu/mpc8220/i2cCore.c b/cpu/mpc8220/i2cCore.c deleted file mode 100644 index b89ad03..0000000 --- a/cpu/mpc8220/i2cCore.c +++ /dev/null @@ -1,627 +0,0 @@ -/* 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 sysMsDelay -01a,19jan04,tcl 1.1 created and seperated from i2c.c -*/ - -/* -DESCRIPTION -This 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_I2CCORE -int 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; - - return i; -} - -STATUS i2c_writeblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data) -{ - int Length = pi2cSet->xfer_size; - -#ifdef TWOBYTES - UINT16 ByteOffset = pi2cSet->str_adr; -#else - UINT8 ByteOffset = pi2cSet->str_adr; -#endif - int j, k; - - I2CCDBG (L2, ("i2c_writeblock\n", 0, 0, 0, 0, 0, 0)); - - if (pi2c->sr & I2C_STA_AL) { - /* Check if arbitration lost */ - I2CCDBG (L2, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0)); - pi2c->sr &= ~I2C_STA_AL; /* Clear the condition */ - return ERROR; - } - - pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ - - /* Do the not even offset first */ - if ((ByteOffset % 8) != 0) { - int remain; - - if (Length > 8) { - remain = 8 - (ByteOffset % 8); - Length -= remain; - - pi2cSet->str_adr = ByteOffset; - - if (i2c_start (pi2c, pi2cSet) == ERROR) - return ERROR; - - for (j = ByteOffset; j < remain; j++) { - if (i2c_writebyte (pi2c, Data++) != OK) - return ERROR; - } - - if (i2c_stop (pi2c) == ERROR) - return ERROR; - - sysMsDelay (32); - - /* Update the new ByteOffset */ - ByteOffset += remain; - } - } - - for (j = ByteOffset, k = 0; j < (Length + ByteOffset); j++) { - if ((j % 8) == 0) { - pi2cSet->str_adr = j; - if (i2c_start (pi2c, pi2cSet) == ERROR) - return ERROR; - } - - k++; - - if (i2c_writebyte (pi2c, Data++) != OK) - return ERROR; - - if ((j == (Length - 1)) || ((k % 8) == 0)) { - if (i2c_stop (pi2c) == ERROR) - return ERROR; - - sysMsDelay (50); - } - - } - - return k; -} - -STATUS i2c_readbyte (SI2C * pi2c, UINT8 * readb, int *index) -{ - pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt Bit */ - *readb = pi2c->dr; /* Read a byte */ - - /* - Set I2C_CTRL_TXAK will cause Transfer pending and - set I2C_CTRL_STA will cause Interrupt pending - */ - if (*index != 2) { - if (chk_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ - return ERROR; - } - - if (*index != 1) { - if (chk_status (pi2c, I2C_STA_IF, 1) != OK) - return ERROR; - } - - return (OK); -} - - -STATUS i2c_writebyte (SI2C * pi2c, UINT8 * writeb) -{ - pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt */ - pi2c->dr = *writeb; /* Write a byte */ - - if (chk_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ - return ERROR; - - if (chk_status (pi2c, I2C_STA_IF, 1) != OK) - return ERROR; - - return OK; -} - -STATUS i2c_write2byte (SI2C * pi2c, UINT16 * writeb) -{ - UINT8 data; - - data = (UINT8) ((*writeb >> 8) & 0xff); - if (i2c_writebyte (pi2c, &data) != OK) - return ERROR; - data = (UINT8) (*writeb & 0xff); - if (i2c_writebyte (pi2c, &data) != OK) - return ERROR; - return OK; -} - -/* FDR table base on 33MHz - more detail please refer to Odini2c_dividers.xls -FDR FDR scl sda scl2tap2 -510 432 tap tap tap tap scl_per sda_hold I2C Freq 0 1 2 3 4 5 -000 000 9 3 4 1 28 Clocks 9 Clocks 1190 KHz 0 0 0 0 0 0 -000 001 9 3 4 2 44 Clocks 11 Clocks 758 KHz 0 0 1 0 0 0 -000 010 9 3 6 4 80 Clocks 17 Clocks 417 KHz 0 0 0 1 0 0 -000 011 9 3 6 8 144 Clocks 25 Clocks 231 KHz 0 0 1 1 0 0 -000 100 9 3 14 16 288 Clocks 49 Clocks 116 KHz 0 0 0 0 1 0 -000 101 9 3 30 32 576 Clocks 97 Clocks 58 KHz 0 0 1 0 1 0 -000 110 9 3 62 64 1152 Clocks 193 Clocks 29 KHz 0 0 0 1 1 0 -000 111 9 3 126 128 2304 Clocks 385 Clocks 14 KHz 0 0 1 1 1 0 -001 000 10 3 4 1 30 Clocks 9 Clocks 1111 KHz1 0 0 0 0 0 -001 001 10 3 4 2 48 Clocks 11 Clocks 694 KHz 1 0 1 0 0 0 -001 010 10 3 6 4 88 Clocks 17 Clocks 379 KHz 1 0 0 1 0 0 -001 011 10 3 6 8 160 Clocks 25 Clocks 208 KHz 1 0 1 1 0 0 -001 100 10 3 14 16 320 Clocks 49 Clocks 104 KHz 1 0 0 0 1 0 -001 101 10 3 30 32 640 Clocks 97 Clocks 52 KHz 1 0 1 0 1 0 -001 110 10 3 62 64 1280 Clocks 193 Clocks 26 KHz 1 0 0 1 1 0 -001 111 10 3 126 128 2560 Clocks 385 Clocks 13 KHz 1 0 1 1 1 0 -010 000 12 4 4 1 34 Clocks 10 Clocks 980 KHz 0 1 0 0 0 0 -010 001 12 4 4 2 56 Clocks 13 Clocks 595 KHz 0 1 1 0 0 0 -010 010 12 4 6 4 104 Clocks 21 Clocks 321 KHz 0 1 0 1 0 0 -010 011 12 4 6 8 192 Clocks 33 Clocks 174 KHz 0 1 1 1 0 0 -010 100 12 4 14 16 384 Clocks 65 Clocks 87 KHz 0 1 0 0 1 0 -010 101 12 4 30 32 768 Clocks 129 Clocks 43 KHz 0 1 1 0 1 0 -010 110 12 4 62 64 1536 Clocks 257 Clocks 22 KHz 0 1 0 1 1 0 -010 111 12 4 126 128 3072 Clocks 513 Clocks 11 KHz 0 1 1 1 1 0 -011 000 15 4 4 1 40 Clocks 10 Clocks 833 KHz 1 1 0 0 0 0 -011 001 15 4 4 2 68 Clocks 13 Clocks 490 KHz 1 1 1 0 0 0 -011 010 15 4 6 4 128 Clocks 21 Clocks 260 KHz 1 1 0 1 0 0 -011 011 15 4 6 8 240 Clocks 33 Clocks 139 KHz 1 1 1 1 0 0 -011 100 15 4 14 16 480 Clocks 65 Clocks 69 KHz 1 1 0 0 1 0 -011 101 15 4 30 32 960 Clocks 129 Clocks 35 KHz 1 1 1 0 1 0 -011 110 15 4 62 64 1920 Clocks 257 Clocks 17 KHz 1 1 0 1 1 0 -011 111 15 4 126 128 3840 Clocks 513 Clocks 9 KHz 1 1 1 1 1 0 -100 000 5 1 4 1 20 Clocks 7 Clocks 1667 KHz 0 0 0 0 0 1 -100 001 5 1 4 2 28 Clocks 7 Clocks 1190 KHz 0 0 1 0 0 1 -100 010 5 1 6 4 48 Clocks 9 Clocks 694 KHz 0 0 0 1 0 1 -100 011 5 1 6 8 80 Clocks 9 Clocks 417 KHz 0 0 1 1 0 1 -100 100 5 1 14 16 160 Clocks 17 Clocks 208 KHz 0 0 0 0 1 1 -100 101 5 1 30 32 320 Clocks 33 Clocks 104 KHz 0 0 1 0 1 1 -100 110 5 1 62 64 640 Clocks 65 Clocks 52 KHz 0 0 0 1 1 1 -100 111 5 1 126 128 1280 Clocks 129 Clocks 26 KHz 0 0 1 1 1 1 -101 000 6 1 4 1 22 Clocks 7 Clocks 1515 KHz 1 0 0 0 0 1 -101 001 6 1 4 2 32 Clocks 7 Clocks 1042 KHz 1 0 1 0 0 1 -101 010 6 1 6 4 56 Clocks 9 Clocks 595 KHz 1 0 0 1 0 1 -101 011 6 1 6 8 96 Clocks 9 Clocks 347 KHz 1 0 1 1 0 1 -101 100 6 1 14 16 192 Clocks 17 Clocks 174 KHz 1 0 0 0 1 1 -101 101 6 1 30 32 384 Clocks 33 Clocks 87 KHz 1 0 1 0 1 1 -101 110 6 1 62 64 768 Clocks 65 Clocks 43 KHz 1 0 0 1 1 1 -101 111 6 1 126 128 1536 Clocks 129 Clocks 22 KHz 1 0 1 1 1 1 -110 000 7 2 4 1 24 Clocks 8 Clocks 1389 KHz 0 1 0 0 0 1 -110 001 7 2 4 2 36 Clocks 9 Clocks 926 KHz 0 1 1 0 0 1 -110 010 7 2 6 4 64 Clocks 13 Clocks 521 KHz 0 1 0 1 0 1 -110 011 7 2 6 8 112 Clocks 17 Clocks 298 KHz 0 1 1 1 0 1 -110 100 7 2 14 16 224 Clocks 33 Clocks 149 KHz 0 1 0 0 1 1 -110 101 7 2 30 32 448 Clocks 65 Clocks 74 KHz 0 1 1 0 1 1 -110 110 7 2 62 64 896 Clocks 129 Clocks 37 KHz 0 1 0 1 1 1 -110 111 7 2 126 128 1792 Clocks 257 Clocks 19 KHz 0 1 1 1 1 1 -111 000 8 2 4 1 26 Clocks 8 Clocks 1282 KHz 1 1 0 0 0 1 -111 001 8 2 4 2 40 Clocks 9 Clocks 833 KHz 1 1 1 0 0 1 -111 010 8 2 6 4 72 Clocks 13 Clocks 463 KHz 1 1 0 1 0 1 -111 011 8 2 6 8 128 Clocks 17 Clocks 260 KHz 1 1 1 1 0 1 -111 100 8 2 14 16 256 Clocks 33 Clocks 130 KHz 1 1 0 0 1 1 -111 101 8 2 30 32 512 Clocks 65 Clocks 65 KHz 1 1 1 0 1 1 -111 110 8 2 62 64 1024 Clocks 129 Clocks 33 KHz 1 1 0 1 1 1 -111 111 8 2 126 128 2048 Clocks 257 Clocks 16 KHz 1 1 1 1 1 1 -*/ -STATUS SetI2cFDR (PSI2C pi2cRegs, int bitrate) -{ -/* Constants */ - const UINT8 div_hold[8][3] = { {9, 3}, {10, 3}, - {12, 4}, {15, 4}, - {5, 1}, {6, 1}, - {7, 2}, {8, 2} - }; - - const UINT8 scl_tap[8][2] = { {4, 1}, {4, 2}, - {6, 4}, {6, 8}, - {14, 16}, {30, 32}, - {62, 64}, {126, 128} - }; - - UINT8 mfdr_bits; - - int i = 0; - int j = 0; - - int Diff, min; - int WhichFreq, iRec, jRec; - int SCL_Period; - int SCL_Hold; - int I2C_Freq; - - I2CCDBG (L2, ("Entering getBitRate: bitrate %d pi2cRegs 0x%08x\n", - bitrate, (int) pi2cRegs, 0, 0, 0, 0)); - - if (bitrate < 0) { - I2CCDBG (NO, ("Invalid bitrate\n", 0, 0, 0, 0, 0, 0)); - return ERROR; - } - - /* Initialize */ - mfdr_bits = 0; - min = 0x7fffffff; - WhichFreq = iRec = jRec = 0; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - /* SCL Period = 2 * (scl2tap + [(SCL_Tap - 1) * tap2tap] + 2) - * SCL Hold = scl2tap + ((SDA_Tap - 1) * tap2tap) + 3 - * Bit Rate (I2C Freq) = System Freq / SCL Period - */ - SCL_Period = - 2 * (scl_tap[i][0] + - ((div_hold[j][0] - 1) * scl_tap[i][1]) + - 2); - - /* Now get the I2C Freq */ - I2C_Freq = DEV_CLOCK_FREQ / SCL_Period; - - /* Take equal or slower */ - if (I2C_Freq > bitrate) - continue; - - /* Take the differences */ - Diff = I2C_Freq - bitrate; - - Diff = ABS (Diff); - - /* Find the closer value */ - if (Diff < min) { - min = Diff; - WhichFreq = I2C_Freq; - iRec = i; - jRec = j; - } - - I2CCDBG (L2, - ("--- (%d,%d) I2C_Freq %d minDiff %d min %d\n", - i, j, I2C_Freq, Diff, min, 0)); - } - } - - SCL_Period = - 2 * (scl_tap[iRec][0] + - ((div_hold[jRec][0] - 1) * scl_tap[iRec][1]) + 2); - - I2CCDBG (L2, ("\nmin %d WhichFreq %d iRec %d jRec %d\n", - min, WhichFreq, iRec, jRec, 0, 0)); - I2CCDBG (L2, ("--- scl2tap %d SCL_Tap %d tap2tap %d\n", - scl_tap[iRec][0], div_hold[jRec][0], scl_tap[iRec][1], - 0, 0, 0)); - - /* This may no require */ - SCL_Hold = - scl_tap[iRec][0] + - ((div_hold[jRec][1] - 1) * scl_tap[iRec][1]) + 3; - I2CCDBG (L2, - ("--- SCL_Period %d SCL_Hold %d\n", SCL_Period, SCL_Hold, 0, - 0, 0, 0)); - - I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0)); - - /* FDR 4,3,2 */ - if ((iRec & 1) == 1) - mfdr_bits |= 0x04; /* FDR 2 */ - if ((iRec & 2) == 2) - mfdr_bits |= 0x08; /* FDR 3 */ - if ((iRec & 4) == 4) - mfdr_bits |= 0x10; /* FDR 4 */ - /* FDR 5,1,0 */ - if ((jRec & 1) == 1) - mfdr_bits |= 0x01; /* FDR 0 */ - if ((jRec & 2) == 2) - mfdr_bits |= 0x02; /* FDR 1 */ - if ((jRec & 4) == 4) - mfdr_bits |= 0x20; /* FDR 5 */ - - I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0)); - - pi2cRegs->fdr = mfdr_bits; - - return OK; -} |