-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathI2C.c
105 lines (79 loc) · 4.52 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
/* Copyright (C) 2015 Kristian Sloth Lauszus. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Sloth Lauszus
Web : http://www.lauszus.com
e-mail : [email protected]
*/
#include <stdint.h>
#include <stdbool.h>
#include "I2C.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
void initI2C(void) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // Enable I2C1 peripheral
SysCtlDelay(2); // Insert a few cycles after enabling the peripheral to allow the clock to be fully activated
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable GPIOA peripheral
SysCtlDelay(2); // Insert a few cycles after enabling the peripheral to allow the clock to be fully activated
// Use alternate function
GPIOPinConfigure(GPIO_PA6_I2C1SCL);
GPIOPinConfigure(GPIO_PA7_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6); // Use pin with I2C SCL peripheral
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7); // Use pin with I2C peripheral
I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), true); // Enable and set frequency to 400 kHz
SysCtlDelay(2); // Insert a few cycles after enabling the I2C to allow the clock to be fully activated
}
void i2cWrite(uint8_t addr, uint8_t regAddr, uint8_t data) {
i2cWriteData(addr, regAddr, &data, 1);
}
void i2cWriteData(uint8_t addr, uint8_t regAddr, uint8_t *data, uint8_t length) {
I2CMasterSlaveAddrSet(I2C1_BASE, addr, false); // Set to write mode
I2CMasterDataPut(I2C1_BASE, regAddr); // Place address into data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send start condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
for (uint8_t i = 0; i < length - 1; i++) {
I2CMasterDataPut(I2C1_BASE, data[i]); // Place data into data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); // Send continues condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
}
I2CMasterDataPut(I2C1_BASE, data[length - 1]); // Place data into data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); // Send finish condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
}
uint8_t i2cRead(uint8_t addr, uint8_t regAddr) {
I2CMasterSlaveAddrSet(I2C1_BASE, addr, false); // Set to write mode
I2CMasterDataPut(I2C1_BASE, regAddr); // Place address into data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND); // Send data
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
I2CMasterSlaveAddrSet(I2C1_BASE, addr, true); // Set to read mode
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); // Tell master to read data
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
return I2CMasterDataGet(I2C1_BASE); // Read data
}
void i2cReadData(uint8_t addr, uint8_t regAddr, uint8_t *data, uint8_t length) {
I2CMasterSlaveAddrSet(I2C1_BASE, addr, false); // Set to write mode
I2CMasterDataPut(I2C1_BASE, regAddr); // Place address into data register
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND); // Send data
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
I2CMasterSlaveAddrSet(I2C1_BASE, addr, true); // Set to read mode
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); // Send start condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
data[0] = I2CMasterDataGet(I2C1_BASE); // Place data into data register
for (uint8_t i = 1; i < length - 1; i++) {
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT); // Send continues condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
data[i] = I2CMasterDataGet(I2C1_BASE); // Place data into data register
}
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); // Send finish condition
while (I2CMasterBusy(I2C1_BASE)); // Wait until transfer is done
data[length - 1] = I2CMasterDataGet(I2C1_BASE); // Place data into data register
}