📄 i2ccore.c
字号:
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.xlsFDR FDR scl sda scl2tap2510 432 tap tap tap tap scl_per sda_hold I2C Freq 0 1 2 3 4 5000 000 9 3 4 1 28 Clocks 9 Clocks 1190 KHz 0 0 0 0 0 0000 001 9 3 4 2 44 Clocks 11 Clocks 758 KHz 0 0 1 0 0 0000 010 9 3 6 4 80 Clocks 17 Clocks 417 KHz 0 0 0 1 0 0000 011 9 3 6 8 144 Clocks 25 Clocks 231 KHz 0 0 1 1 0 0000 100 9 3 14 16 288 Clocks 49 Clocks 116 KHz 0 0 0 0 1 0000 101 9 3 30 32 576 Clocks 97 Clocks 58 KHz 0 0 1 0 1 0000 110 9 3 62 64 1152 Clocks 193 Clocks 29 KHz 0 0 0 1 1 0000 111 9 3 126 128 2304 Clocks 385 Clocks 14 KHz 0 0 1 1 1 0001 000 10 3 4 1 30 Clocks 9 Clocks 1111 KHz1 0 0 0 0 0001 001 10 3 4 2 48 Clocks 11 Clocks 694 KHz 1 0 1 0 0 0001 010 10 3 6 4 88 Clocks 17 Clocks 379 KHz 1 0 0 1 0 0001 011 10 3 6 8 160 Clocks 25 Clocks 208 KHz 1 0 1 1 0 0001 100 10 3 14 16 320 Clocks 49 Clocks 104 KHz 1 0 0 0 1 0001 101 10 3 30 32 640 Clocks 97 Clocks 52 KHz 1 0 1 0 1 0001 110 10 3 62 64 1280 Clocks 193 Clocks 26 KHz 1 0 0 1 1 0001 111 10 3 126 128 2560 Clocks 385 Clocks 13 KHz 1 0 1 1 1 0010 000 12 4 4 1 34 Clocks 10 Clocks 980 KHz 0 1 0 0 0 0010 001 12 4 4 2 56 Clocks 13 Clocks 595 KHz 0 1 1 0 0 0010 010 12 4 6 4 104 Clocks 21 Clocks 321 KHz 0 1 0 1 0 0010 011 12 4 6 8 192 Clocks 33 Clocks 174 KHz 0 1 1 1 0 0010 100 12 4 14 16 384 Clocks 65 Clocks 87 KHz 0 1 0 0 1 0010 101 12 4 30 32 768 Clocks 129 Clocks 43 KHz 0 1 1 0 1 0010 110 12 4 62 64 1536 Clocks 257 Clocks 22 KHz 0 1 0 1 1 0010 111 12 4 126 128 3072 Clocks 513 Clocks 11 KHz 0 1 1 1 1 0011 000 15 4 4 1 40 Clocks 10 Clocks 833 KHz 1 1 0 0 0 0011 001 15 4 4 2 68 Clocks 13 Clocks 490 KHz 1 1 1 0 0 0011 010 15 4 6 4 128 Clocks 21 Clocks 260 KHz 1 1 0 1 0 0011 011 15 4 6 8 240 Clocks 33 Clocks 139 KHz 1 1 1 1 0 0011 100 15 4 14 16 480 Clocks 65 Clocks 69 KHz 1 1 0 0 1 0011 101 15 4 30 32 960 Clocks 129 Clocks 35 KHz 1 1 1 0 1 0011 110 15 4 62 64 1920 Clocks 257 Clocks 17 KHz 1 1 0 1 1 0011 111 15 4 126 128 3840 Clocks 513 Clocks 9 KHz 1 1 1 1 1 0100 000 5 1 4 1 20 Clocks 7 Clocks 1667 KHz 0 0 0 0 0 1100 001 5 1 4 2 28 Clocks 7 Clocks 1190 KHz 0 0 1 0 0 1100 010 5 1 6 4 48 Clocks 9 Clocks 694 KHz 0 0 0 1 0 1100 011 5 1 6 8 80 Clocks 9 Clocks 417 KHz 0 0 1 1 0 1100 100 5 1 14 16 160 Clocks 17 Clocks 208 KHz 0 0 0 0 1 1100 101 5 1 30 32 320 Clocks 33 Clocks 104 KHz 0 0 1 0 1 1100 110 5 1 62 64 640 Clocks 65 Clocks 52 KHz 0 0 0 1 1 1100 111 5 1 126 128 1280 Clocks 129 Clocks 26 KHz 0 0 1 1 1 1101 000 6 1 4 1 22 Clocks 7 Clocks 1515 KHz 1 0 0 0 0 1101 001 6 1 4 2 32 Clocks 7 Clocks 1042 KHz 1 0 1 0 0 1101 010 6 1 6 4 56 Clocks 9 Clocks 595 KHz 1 0 0 1 0 1101 011 6 1 6 8 96 Clocks 9 Clocks 347 KHz 1 0 1 1 0 1101 100 6 1 14 16 192 Clocks 17 Clocks 174 KHz 1 0 0 0 1 1101 101 6 1 30 32 384 Clocks 33 Clocks 87 KHz 1 0 1 0 1 1101 110 6 1 62 64 768 Clocks 65 Clocks 43 KHz 1 0 0 1 1 1101 111 6 1 126 128 1536 Clocks 129 Clocks 22 KHz 1 0 1 1 1 1110 000 7 2 4 1 24 Clocks 8 Clocks 1389 KHz 0 1 0 0 0 1110 001 7 2 4 2 36 Clocks 9 Clocks 926 KHz 0 1 1 0 0 1110 010 7 2 6 4 64 Clocks 13 Clocks 521 KHz 0 1 0 1 0 1110 011 7 2 6 8 112 Clocks 17 Clocks 298 KHz 0 1 1 1 0 1110 100 7 2 14 16 224 Clocks 33 Clocks 149 KHz 0 1 0 0 1 1110 101 7 2 30 32 448 Clocks 65 Clocks 74 KHz 0 1 1 0 1 1110 110 7 2 62 64 896 Clocks 129 Clocks 37 KHz 0 1 0 1 1 1110 111 7 2 126 128 1792 Clocks 257 Clocks 19 KHz 0 1 1 1 1 1111 000 8 2 4 1 26 Clocks 8 Clocks 1282 KHz 1 1 0 0 0 1111 001 8 2 4 2 40 Clocks 9 Clocks 833 KHz 1 1 1 0 0 1111 010 8 2 6 4 72 Clocks 13 Clocks 463 KHz 1 1 0 1 0 1111 011 8 2 6 8 128 Clocks 17 Clocks 260 KHz 1 1 1 1 0 1111 100 8 2 14 16 256 Clocks 33 Clocks 130 KHz 1 1 0 0 1 1111 101 8 2 30 32 512 Clocks 65 Clocks 65 KHz 1 1 1 0 1 1111 110 8 2 62 64 1024 Clocks 129 Clocks 33 KHz 1 1 0 1 1 1111 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -