Skip to content

Commit abac01a

Browse files
authored
Create i2c.h
1 parent 2dfe3e0 commit abac01a

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

  • Mini_LED_Gamer/Mini_LED_Gamer
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// This library provides the high-level functions needed to use the I2C
2+
// serial interface supported by the hardware of several AVR processors.
3+
#ifndef i2c_h
4+
#define i2c_h
5+
6+
#include <avr/io.h>
7+
8+
// TWSR values (status codes)
9+
// Master
10+
#define TW_START 0x08
11+
#define TW_REP_START 0x10
12+
// Master Transmitter
13+
#define TW_MT_SLA_ACK 0x18
14+
#define TW_MT_SLA_NACK 0x20
15+
#define TW_MT_DATA_ACK 0x28
16+
#define TW_MT_DATA_NACK 0x30
17+
#define TW_MT_ARB_LOST 0x38
18+
// Master Receiver
19+
#define TW_MR_ARB_LOST 0x38
20+
#define TW_MR_SLA_ACK 0x40
21+
#define TW_MR_SLA_NACK 0x48
22+
#define TW_MR_DATA_ACK 0x50
23+
#define TW_MR_DATA_NACK 0x58
24+
// Slave Transmitter
25+
#define TW_ST_SLA_ACK 0xA8
26+
#define TW_ST_ARB_LOST_SLA_ACK 0xB0
27+
#define TW_ST_DATA_ACK 0xB8
28+
#define TW_ST_DATA_NACK 0xC0
29+
#define TW_ST_LAST_DATA 0xC8
30+
// Slave Receiver
31+
#define TW_SR_SLA_ACK 0x60
32+
#define TW_SR_ARB_LOST_SLA_ACK 0x68
33+
#define TW_SR_GCALL_ACK 0x70
34+
#define TW_SR_ARB_LOST_GCALL_ACK 0x78
35+
#define TW_SR_DATA_ACK 0x80
36+
#define TW_SR_DATA_NACK 0x88
37+
#define TW_SR_GCALL_DATA_ACK 0x90
38+
#define TW_SR_GCALL_DATA_NACK 0x98
39+
#define TW_SR_STOP 0xA0
40+
// Misc
41+
#define TW_NO_INFO 0xF8
42+
#define TW_BUS_ERROR 0x00
43+
44+
// defines and constants
45+
#define TWCR_CMD_MASK 0x0F
46+
#define TWSR_STATUS_MASK 0xF8
47+
48+
// return values
49+
#define I2C_OK 0x00
50+
#define I2C_ERROR_NODEV 0x01
51+
52+
//! Initialize I2C (TWI) interface
53+
void i2cInit(void);
54+
// Low-level I2C transaction commands
55+
//! Send an I2C start condition in Master mode
56+
void i2cSendStart(void);
57+
//! Send an I2C stop condition in Master mode
58+
void i2cSendStop(void);
59+
//! Wait for current I2C operation to complete
60+
void i2cWaitForComplete(void);
61+
//! Send an (address|R/W) combination or a data byte over I2C
62+
void i2cSendByte(unsigned char data);
63+
//! Receive a data byte over I2C
64+
// ackFlag = -1 if recevied data should be ACK'ed
65+
// ackFlag = 0 if recevied data should be NACK'ed
66+
void i2cReceiveByte(unsigned char ackFlag);
67+
//! Pick up the data that was received with i2cReceiveByte()
68+
unsigned char i2cGetReceivedByte(void);
69+
//! Get current I2c bus status from TWSR
70+
unsigned char i2cGetStatus(void);
71+
void delay_10us(uint16_t x);
72+
73+
/*********************
74+
****I2C Functions****
75+
*********************/
76+
77+
void i2cInit(void){
78+
// set SCL freq = F_CPU/(16+2*TWBR*4^TWPS))=16*10^6/(16+2*12)=400kHz
79+
TWSR &= ~(_BV(TWPS0)|_BV(TWPS1)); // clear TWPS in TWSR register, setting prescaler(TWPS) = 0
80+
TWBR = 12; // set bit rate register (12 -> 400kHz; 32 -> 200kHz)
81+
TWCR |= _BV(TWEN); // Enable TWI
82+
}
83+
84+
void i2cSendStart(void){
85+
// send start condition
86+
TWCR = _BV(TWINT)|_BV(TWSTA)|_BV(TWEN);
87+
}
88+
89+
void i2cSendStop(void){
90+
// transmit stop condition
91+
TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWSTO);
92+
}
93+
94+
void i2cWaitForComplete(void){
95+
// wait for i2c interface to complete operation, use i for timeout
96+
uint8_t i = 0;
97+
while ((!(TWCR & (1<<TWINT))) && (i < 90))
98+
i++;
99+
}
100+
101+
void i2cSendByte(uint8_t data){
102+
delay_10us(1);
103+
TWDR = data; // save data to the TWDR
104+
TWCR = (1<<TWINT) | (1<<TWEN); // begin send
105+
}
106+
107+
void i2cReceiveByte(uint8_t ackFlag){
108+
if( ackFlag ){
109+
// ackFlag = 1: ACK the recevied data (would like to receive more data)
110+
TWCR = (TWCR&TWCR_CMD_MASK)|_BV(TWINT)|_BV(TWEA);
111+
}
112+
else{
113+
// ackFlag = 0: NACK the recevied data (want to stop receiving data)
114+
TWCR = (TWCR&TWCR_CMD_MASK)|_BV(TWINT);
115+
}
116+
}
117+
118+
unsigned char i2cGetReceivedByte(void) {
119+
// retieve received data byte from i2c TWDR
120+
return(TWDR);
121+
}
122+
123+
unsigned char i2cGetStatus(void){
124+
// retieve current i2c status from i2c TWSR
125+
return(TWSR);
126+
}
127+
128+
void delay_10us(uint16_t x){
129+
for (; x > 0 ; x--){
130+
for (uint8_t y = 0 ; y < 25; y++){
131+
asm volatile ("nop");
132+
}
133+
}
134+
}
135+
136+
/*********************
137+
****I2C High Level Functions****
138+
*********************/
139+
140+
void writeRegister(uint8_t address, uint8_t data){
141+
i2cSendStart();
142+
i2cWaitForComplete();
143+
i2cSendByte((address<<1));
144+
i2cWaitForComplete();
145+
i2cSendByte(data);
146+
i2cWaitForComplete();
147+
i2cSendStop();
148+
}
149+
150+
void writeRegisters(uint8_t address, uint8_t regsiter, uint8_t i, uint16_t *data){
151+
i2cSendStart();
152+
i2cWaitForComplete();
153+
i2cSendByte((address<<1));
154+
i2cWaitForComplete();
155+
i2cSendByte(regsiter);
156+
i2cWaitForComplete();
157+
158+
for (uint8_t j=0;j<i;j++) {
159+
i2cSendByte(data[j]&255);
160+
i2cWaitForComplete();
161+
i2cSendByte((data[j]>>8)&255);
162+
i2cWaitForComplete();
163+
}
164+
i2cSendStop();
165+
}
166+
167+
uint8_t readRegister(uint8_t address, uint8_t regsiter){
168+
i2cSendStart();
169+
i2cWaitForComplete();
170+
i2cSendByte((address<<1));
171+
i2cWaitForComplete();
172+
i2cSendByte(regsiter);
173+
i2cWaitForComplete();
174+
175+
i2cSendStart();
176+
i2cWaitForComplete();
177+
i2cSendByte((address<<1)|0x01);
178+
i2cWaitForComplete();
179+
i2cReceiveByte(0);
180+
i2cWaitForComplete();
181+
uint8_t data = i2cGetReceivedByte();
182+
i2cSendStop();
183+
184+
return data;
185+
}
186+
187+
#endif

0 commit comments

Comments
 (0)