📄 i2c.c
字号:
/****************************** MX1 I2C / iMagic Driver*******************************/#include "khead.h"#include "mx1hw.h"#include "i2c.h"#include "csi.h"//// Global//static U32 init = 0;//// MX1 Port enable// for I2C signals//static void port_init_I2C(void){ // PA15 : I2C_DATA // PA16 : I2C_CLK *(U32 *) PTA_GIUS &= ~0x00018000; return;}//// Sensor Register Write//// Description// ===========// Write 16-bit data into sensor register//// Flow// ====// START signal => Device write addr => MSB => LSB => STOP signal//// Input / Output// ==============// I : (1) Register Addr// (2) 16-bit data// O : void//U32 I2C_write(U32 reg, U32 data){ U8 msb, lsb; U32 error_no_ack = 0; if (!init) { port_init_I2C(); init = 1; } //decompose 16-bit data into 2 bytes msb = (data & 0xFF00) >> 8; lsb = data & 0x00FF; //module reset *(U32 *) I2C_I2CR = (U32) 0x0; //I2C init *(U32 *) I2C_IFDR = (U32) I2C_CLKDIV; //clock select *(U32 *) I2C_I2CR |= (U32) 0x80; //I2C enable *(U32 *) I2C_I2CR |= (U32) 0x08; //ack disable //grant bus master *(U32 *) I2C_I2CR |= (U32) 0x20; //gen START signal while (!(*(U32 *) I2C_I2SR & (U32) 0x20)); //poll until bus is grant (IBB bit) //enter transmit mode *(U32 *) I2C_I2CR |= (U32) 0x10; //transmit mode //transmit device slave calling addr *(U32 *) I2C_I2DR = SA_W; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //transmit register addr *(U32 *) I2C_I2DR = reg; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //transmit data MSB *(U32 *) I2C_I2DR = msb; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //transmit data LSB *(U32 *) I2C_I2DR = lsb; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //generate STOP signal *(U32 *) I2C_I2CR &= (U32) ~ 0x20; //enter slave mode while (*(U32 *) I2C_I2SR & (U32) 0x20); //poll until bus is release (IBB = 0) //disable I2C *(U32 *) I2C_I2CR = (U32) 0x0; if (error_no_ack) return 1; else return 0;}//// Sensor Register Read//// Description// ===========// Read 16-bit data into sensor register//// Flow// ====// START signal => Device write addr => Repeated START// => Device read addr => MSB (with ACK) => LSB (with NACK)// => STOP signal//// Input / Output// ==============// I : (1) Register Addr// (2) 16-bit data// O : void//U32 I2C_read(U32 reg, U32 * _data){ U32 error_no_ack = 0; U32 msb, lsb; if (!init) { port_init_I2C(); init = 1; } //module reset *(U32 *) I2C_I2CR = (U32) 0x0; //I2C init *(U32 *) I2C_IFDR = (U32) I2C_CLKDIV; //clock select *(U32 *) I2C_I2CR |= (U32) 0x80; //I2C enable //grant bus master *(U32 *) I2C_I2CR |= (U32) 0x20; //gen START signal while (!(*(U32 *) I2C_I2SR & (U32) 0x20)); //poll until bus is grant (IBB bit) //enter transmit mode *(U32 *) I2C_I2CR |= (U32) 0x10; //transmit device addr for WRITE *(U32 *) I2C_I2DR = SA_W; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //transmit register addr *(U32 *) I2C_I2DR = reg; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //generate repeated START signal *(U32 *) I2C_I2CR |= (U32) 0x4; //transmit device calling addr for READ *(U32 *) I2C_I2DR = SA_R; //initiate transfer while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //check for ACK bit if (*(U32 *) I2C_I2SR & 0x1) error_no_ack = 1; //change to recieve mode *(U32 *) I2C_I2CR &= (U32) ~ 0x10; //dummy read to excite clock generation *(U32 *) I2C_I2CR &= ~0x08; //ack enable msb = *(U32 *) I2C_I2DR; while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //get MSB, and gen clock for reading LSB *(U32 *) I2C_I2CR |= 0x08; //ack disable msb = *(U32 *) I2C_I2DR; while (!(*(U32 *) I2C_I2SR & 0x02)); //poll IIF bit *(U32 *) I2C_I2SR &= ~0x02; //must clear IIF bit //generate STOP signal *(U32 *) I2C_I2CR &= (U32) ~ 0x20; //enter slave mode while (*(U32 *) I2C_I2SR & (U32) 0x20); //poll until bus is release (IBB = 0) //get LSB lsb = *(U32 *) I2C_I2DR; //disable I2C *(U32 *) I2C_I2CR = (U32) 0x0; //concantenate 2 bytes into 16-bit *_data = (msb << 8) | lsb; if (error_no_ack) return 1; else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -