-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathi2c.c
177 lines (149 loc) · 6.39 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/**
******************************************************************************
* @file i2c.c
* @author William Xu
* @version V1.0.0
* @date 9-Apr-2018
* @brief I2C sensor rw driver
******************************************************************************
*
* Copyright (c) 2009-2018 MXCHIP Co.,Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#include <stdio.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "system_msp432p401r.h"
#include "tick.h"
/******************************************************************************
* Structures
******************************************************************************/
struct i2c_instance {
uint32_t place_holder;
};
/******************************************************************************
* Variable Definitions
******************************************************************************/
/* I2C Master Configuration Parameter */
const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
12000000, // SMCLK = 12MHz
// EUSCI_B_I2C_SET_DATA_RATE_1MBPS, // Desired I2C Clock of 1Mhz
EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
#define I2C_TIMEOUT 5000
/* NULL handler for this driver, complete in future */
static struct i2c_instance i2c;
/******************************************************************************
* Function Definitions
******************************************************************************/
void* i2c_init(void *config)
{
/* Select Port 6 for I2C - Set Pin 4, 5 to input Primary Module Function,
* (UCB1SIMO/UCB1SDA, UCB1SOMI/UCB1SCL).
*/
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,
GPIO_PIN4 + GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_I2C_setSlaveAddress(EUSCI_B1_BASE, 0x3c);
/* Initializing I2C Master to SMCLK at 400kbs with no autostop */
MAP_I2C_initMaster(EUSCI_B1_BASE, &i2cConfig);
/* Set Master in transmit mode */
MAP_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
/* Enable I2C Module to start operations */
MAP_I2C_enableModule(EUSCI_B1_BASE);
#if 0
/* Enable and clear the interrupt flag */
MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
//Enable master Receive interrupt
MAP_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
#endif
return &i2c;
}
/**
* \brief Sync version of i2c write command
*/
int32_t i2c_cmd_write(uint16_t slave_addr, uint8_t reg, uint8_t *buffer, uint8_t length)
{
int err = 0;
//EUSCI_B_I2C_SENDING_STOP:Transmit STOP condition in master mode
while (MAP_I2C_masterIsStopSent(EUSCI_B1_BASE) == EUSCI_B_I2C_SENDING_STOP);
/* Set Master in transmit mode */
MAP_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
/* Specify slave address */
MAP_I2C_setSlaveAddress(EUSCI_B1_BASE, slave_addr);
//Transmits the first data byte of a multi-byte transmission to the Slave
//主机向从机发送多字节数据的第一个命令字节
MAP_I2C_masterSendMultiByteStartWithTimeout(EUSCI_B1_BASE, reg, I2C_TIMEOUT);
// if (length) MAP_I2C_masterSendMultiByteNextWithTimeout(EUSCI_B1_BASE, reg, I2C_TIMEOUT);
while (length--)
{
MAP_I2C_masterSendMultiByteNextWithTimeout(EUSCI_B1_BASE, *buffer++, I2C_TIMEOUT);
}
MAP_I2C_masterSendMultiByteStopWithTimeout(EUSCI_B1_BASE, I2C_TIMEOUT);
return err;
}
int32_t i2c_cmd_read(uint16_t slave_addr, uint8_t reg, uint8_t *buffer, uint8_t length)
{
uint8_t i;
/* Specify slave address */
MAP_I2C_setSlaveAddress(EUSCI_B1_BASE, slave_addr);
/* Set Master in transmit mode */
MAP_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
//Indicates whether STOP got sent.
while (MAP_I2C_masterIsStopSent(EUSCI_B1_BASE) == EUSCI_B_I2C_SENDING_STOP);
//Starts multi-byte transmission from Master to Slave
I2C_masterSendMultiByteStart(EUSCI_B1_BASE, reg);
//Send STOP byte at the end of a multi-byte transmission from Master to Slave
I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
//Indicates whether STOP got sent.
while (MAP_I2C_masterIsStopSent(EUSCI_B1_BASE) == EUSCI_B_I2C_SENDING_STOP);
/* Set Master in receive mode */
MAP_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_MODE);
delay_ms(100);
for(;;)
{
while (MAP_I2C_masterIsStopSent(EUSCI_B1_BASE) == EUSCI_B_I2C_SENDING_STOP);
I2C_masterReceiveStart(EUSCI_B1_BASE);
//Returns true if the START has been sent, false if it is sending
while(I2C_masterIsStartSent(EUSCI_B1_BASE));
//if Not-acknowledge interrupt
if(I2C_getInterruptStatus(EUSCI_B1_BASE, EUSCI_B_I2C_NAK_INTERRUPT))
{
I2C_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_I2C_NAK_INTERRUPT);
//Sends the STOP at the end of a multi-byte reception at the Master end
I2C_masterReceiveMultiByteStop(EUSCI_B1_BASE);
//Indicates whether STOP got sent.
while(I2C_masterIsStopSent(EUSCI_B1_BASE));
delay_ms(10);
}
else
{
for(i=0; i<length-1; i++)
{
//Does single byte reception from the slave
buffer[i] = I2C_masterReceiveSingle(EUSCI_B1_BASE);
}
buffer[i] = I2C_masterReceiveMultiByteFinish(EUSCI_B1_BASE);
break;
}
}
return 0;
}