-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathqsys_i2c.c
119 lines (94 loc) · 3.4 KB
/
qsys_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
110
111
112
113
114
115
116
117
118
119
#include <stdio.h>
#include <stdint.h>
#include "qsys_i2c.h"
#include "xprintf.h"
/* offsets */
/*
uint32_t tfr_cmd = i2c_base + TFR_CMD_OFFSET;
uint32_t ctrl = i2c_base + CTRL_OFFSET;
uint32_t status = i2c_base + STATUS_OFFSET;
uint32_t iser = i2c_base + ISER_OFFSET;
uint32_t isr = i2c_base + ISR_OFFSET;
uint32_t scl_low = i2c_base + SCL_LOW_OFFSET;
uint32_t scl_high = i2c_base + SCL_HIGH_OFFSET;
uint32_t sda_hold = i2c_base + SDA_HOLD_OFFSET;
*/
void i2c_init(uint32_t i2c_base) {
uint32_t ctrl = i2c_base + CTRL_OFFSET;
uint32_t scl_low = i2c_base + SCL_LOW_OFFSET;
uint32_t scl_high = i2c_base + SCL_HIGH_OFFSET;
uint32_t sda_hold = i2c_base + SDA_HOLD_OFFSET;
// disable I2C
uint32_t ctrl_param = get32(ctrl);
ctrl_param = ctrl_param & 0xFFFFFFFFE;
put32(ctrl, ctrl_param);
// 400kHz config and enable i2c core
uint32_t period = (uint32_t)(I2C_0_FREQ / 400000 / 2) - 1;
put32(scl_low, period);
put32(scl_high, period);
put32(sda_hold, 0x0F);
ctrl_param = get32(ctrl);
ctrl_param |= 0x03;
put32(ctrl, ctrl_param);
}
void i2c_disable_isr(uint32_t i2c_base) {
uint32_t iser = i2c_base + ISER_OFFSET;
put32(iser, 0x00000000);
return;
}
void i2c_start_transmit(uint32_t i2c_base, uint8_t i2c_slave_address, uint8_t is_Read) {
if(1 != is_Read) is_Read = 0; // isRead != 1 : Write
//[31:10]rsv,[9]STA=1, [8]STO=0,[7:1]AD=i2c_slave_address(7bit),[0]RW_D=0
uint32_t tfr_cmd = i2c_base + TFR_CMD_OFFSET;
uint32_t isr = i2c_base + ISR_OFFSET;
// ISR[0]:TX_READY=1?(1:OK to send?)
while(!(get32(isr) & 0x0001)); //while(!(*(volatile uint32_t *)isr & 0x0001));
// send Start + I2C Slave address
if(is_Read){
put32(tfr_cmd, (1U << 9) + (0U << 8) + (i2c_slave_address << 1) + 1);
} // read
else {
put32(tfr_cmd, (1U << 9) + (0U << 8) + (i2c_slave_address << 1) + 0);
} // write
return ;
}
uint32_t i2c_start_receive(uint32_t i2c_base, uint8_t i2c_slave_address) {
return 0;
}
uint32_t i2c_write(uint32_t i2c_base, uint8_t data, bool send_stop_bit) {
uint32_t tfr_cmd = i2c_base + TFR_CMD_OFFSET;
uint32_t status = i2c_base + STATUS_OFFSET;
uint32_t isr = i2c_base + ISR_OFFSET;
// ISR[0]:TX_READY=1?(1:OK to send?)
while(!(get32(isr) & 0x0001)); // while(!(*(volatile uint32_t *)isr & 0x0001));
// send Start + I2C Slave address
if(1U == send_stop_bit) {
put32(tfr_cmd ,(0U << 9) + (1U << 8) + (data));
while(0 == get32(status));
} else {
put32(tfr_cmd ,(0U << 9) + (0U << 8) + (data));
}
return 0;
}
uint32_t i2c_read(uint32_t i2c_base, bool send_stop_bit) {
uint32_t tfr_cmd = i2c_base + TFR_CMD_OFFSET;
uint32_t rx_data = i2c_base + RX_DATA_OFFSET;
uint32_t isr = i2c_base + ISR_OFFSET;
uint32_t status = i2c_base + STATUS_OFFSET;
uint32_t recv_data = 0;
// ISR[0]:TX_READY=1?(1:OK to send?)
while(!(get32(isr) & 0x0001));
if(1U == send_stop_bit) {
put32(tfr_cmd, (0U << 9) + (1U << 8) + (0x00));
// ISR[1]:RX_READY=1?(1:RX finish)
while(0 == (get32(isr) & 0x0002));
recv_data = get32(rx_data);
while(0 == get32(status));
} else {
put32(tfr_cmd, (0U << 9) + (0U << 8) + (0x00));
// ISR[1]:RX_READY=1?(1:RX finish)
while(0 == (get32(isr) & 0x0002));
recv_data = get32(rx_data);
}
return recv_data;
}