/
i2ctools.c
92 lines (76 loc) · 3.28 KB
/
i2ctools.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
#include "inc/hw_types.h"
#include "i2ctools.h"
#include "driverlib/i2c.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
// 80MHz clock so 80,000 is about 1ms
void cheapDelay(unsigned long delay)
{
while(delay--);
}
void i2c_init()
{
// Trying to get around this damn I2C lockup issue
GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_0);
GPIOPinTypeGPIOInput(GPIO_PORTG_BASE, GPIO_PIN_1);
while(!GPIOPinRead(GPIO_PORTG_BASE, GPIO_PIN_1))
{
// Toggle the clock at 100kHz until the slave releases SDA
GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_PIN_0);
cheapDelay(400);
GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_0, ~GPIO_PIN_0);
cheapDelay(400);
}
// Initialize the I2C channel the sensor is connected to
SysCtlPeripheralEnable( SYSCTL_PERIPH_I2C1 );
GPIOPinConfigure( GPIO_PG0_I2C1SCL );
GPIOPinConfigure( GPIO_PG1_I2C1SDA );
GPIOPinTypeI2C( GPIO_PORTG_BASE, GPIO_PIN_0 | GPIO_PIN_1 );
// Set the clock (false = "slow" = 100kbps)
I2CMasterInitExpClk( I2C1_MASTER_BASE, SysCtlClockGet(), false );
I2CMasterEnable( I2C1_MASTER_BASE );
}
void i2c_tx_single(unsigned char SlaveAddr, unsigned char dest, unsigned char data)
{
I2CMasterSlaveAddrSet( I2C1_MASTER_BASE, SlaveAddr, I2C_SEND );
I2CMasterDataPut( I2C1_MASTER_BASE, dest );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START );
while(I2CMasterBusy(I2C1_MASTER_BASE));
I2CMasterDataPut( I2C1_MASTER_BASE, data );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH );
while(I2CMasterBusy(I2C1_MASTER_BASE));
}
unsigned long i2c_rx_single(unsigned char SlaveAddr, unsigned char dest)
{
I2CMasterSlaveAddrSet( I2C1_MASTER_BASE, SlaveAddr, I2C_SEND );
I2CMasterDataPut( I2C1_MASTER_BASE, dest );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
while (I2CMasterBusy( I2C1_MASTER_BASE ));
I2CMasterSlaveAddrSet( I2C1_MASTER_BASE, SlaveAddr, I2C_RECEIVE );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE );
while(I2CMasterBusy( I2C1_MASTER_BASE ));
return I2CMasterDataGet(I2C1_MASTER_BASE);
}
void i2c_rx_multi(unsigned char SlaveAddr, unsigned char dest, unsigned char num_bytes, unsigned long *data)
{
unsigned int i=0;
// Set the address
I2CMasterSlaveAddrSet( I2C1_MASTER_BASE, SlaveAddr, I2C_SEND );
I2CMasterDataPut( I2C1_MASTER_BASE, dest );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
while (I2CMasterBusy( I2C1_MASTER_BASE ));
// Set the address again to tell the device to start sending data
I2CMasterSlaveAddrSet( I2C1_MASTER_BASE, SlaveAddr, I2C_RECEIVE );
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START );
while(I2CMasterBusy( I2C1_MASTER_BASE ));
*data++ = I2CMasterDataGet(I2C1_MASTER_BASE);
while(i++ < (num_bytes-2))
{
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT );
while(I2CMasterBusy( I2C1_MASTER_BASE ));
*data++ = I2CMasterDataGet(I2C1_MASTER_BASE);
}
I2CMasterControl( I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH );
while(I2CMasterBusy( I2C1_MASTER_BASE ));
*data++ = I2CMasterDataGet(I2C1_MASTER_BASE);
}