-
Notifications
You must be signed in to change notification settings - Fork 1
/
i2c.c
109 lines (100 loc) · 2.76 KB
/
i2c.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "i2c.h"
/******************************************************************************\
* Private definitions
\******************************************************************************/
#define SCL 3
#define SDA 4
/******************************************************************************\
* Private prototypes
\******************************************************************************/
void i2c_m_start(void);
void i2c_m_stop(void);
void i2c_m_rstart(void);
void i2c_tran(void);
void i2c_enable(void);
void i2c_disable(void);
void i2c_send(uint8_t);
void i2c_wait(void);
/******************************************************************************\
* Private memory declarations
\******************************************************************************/
static uint8_t error;
static uint16_t timeout;
void I2C_Init(void) {
SIM->SCGC4 |= SIM_SCGC4_I2C0_MASK ; /* clock for I2C0 */
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; /* clock for PORTB */
PORTB->PCR[SCL] |= PORT_PCR_MUX(2); /* I2C0 SCL (PTB3) */
PORTB->PCR[SDA] |= PORT_PCR_MUX(2); /* I2C0 SDA (PTB4) */
I2C0->C1 &= ~(I2C_C1_IICEN_MASK);
I2C0->F |= I2C_F_MULT(1);
I2C0->F |= I2C_F_ICR(0x19);
I2C0->C1 |= I2C_C1_MST_MASK; /* master mode select */
I2C0->C1 |= I2C_C1_TX_MASK; /* enable transfer */
I2C0->C1 |= I2C_C1_TXAK_MASK; /* enable transfer acknowledge */
I2C0->C1 |= I2C_C1_IICIE_MASK;
}
uint8_t I2C_Write(uint8_t address, uint8_t data) {
error = 0x00;
i2c_enable();
i2c_tran(); /* set to transmit mode */
i2c_m_start(); /* send start */
i2c_send((uint8_t)(address << 1)); /* send write address */
i2c_wait(); /* wait for ack from salve */
i2c_send(data); /* send data */
i2c_wait();
i2c_m_stop(); /* set start mask off */
i2c_disable();
return error;
}
/**
* @brief I2C master start.
*/
void i2c_m_start(void) {
I2C0->C1 |= I2C_C1_MST_MASK;
}
/**
* @brief I2C master stop.
*/
void i2c_m_stop(void) {
I2C0->C1 &= ~I2C_C1_MST_MASK;
}
/**
* @brief I2C master restart.
*/
void i2c_m_rstart(void) {
I2C0->C1 |= I2C_C1_RSTA_MASK;
}
/**
* @brief I2C transmit.
*/
void i2c_tran(void) {
I2C0->C1 |= I2C_C1_TX_MASK;
}
/**
* @brief I2C enable.
*/
void i2c_enable(void) {
I2C0->C1 |= I2C_C1_IICEN_MASK;
}
/**
* @brief I2C disable.
*/
void i2c_disable(void) {
I2C0->C1 &= ~I2C_C1_IICEN_MASK;
}
/**
* @brief I2C send data.
*/
void i2c_send(uint8_t data) {
I2C0->D = data;
}
/**
* @brief I2C wait.
*/
void i2c_wait(void) {
timeout = 0;
while (((I2C0->S & I2C_S_IICIF_MASK)==0) && (timeout<10000)) timeout++;
if (timeout >= 10000) error |= I2C_ERR_TIMEOUT;
if ((I2C0->S & I2C_S_RXAK_MASK)==1) error |= I2C_ERR_NOACK;
I2C0->S |= I2C_S_IICIF_MASK;
}