diff options
author | Jack Humbert <jack.humb@gmail.com> | 2018-05-15 22:30:58 -0400 |
---|---|---|
committer | Jack Humbert <jack.humb@gmail.com> | 2018-05-15 22:30:58 -0400 |
commit | 682555faac8a67deff5688b956165cd1c39389cb (patch) | |
tree | 00a0991aed23eee4e2ad3bbcfab202476c7c2676 /drivers/avr/i2c_master.c | |
parent | 6dc215cd679d54ca2ab985c21c9bb299aca74b01 (diff) | |
download | qmk_firmware-682555faac8a67deff5688b956165cd1c39389cb.tar.gz qmk_firmware-682555faac8a67deff5688b956165cd1c39389cb.zip |
i2c fix
Diffstat (limited to 'drivers/avr/i2c_master.c')
-rwxr-xr-x | drivers/avr/i2c_master.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c index f4a4bb7b0..bcf92153c 100755 --- a/drivers/avr/i2c_master.c +++ b/drivers/avr/i2c_master.c | |||
@@ -13,32 +13,34 @@ | |||
13 | 13 | ||
14 | void i2c_init(void) | 14 | void i2c_init(void) |
15 | { | 15 | { |
16 | TWSR = 0; /* no prescaler */ | ||
16 | TWBR = (uint8_t)TWBR_val; | 17 | TWBR = (uint8_t)TWBR_val; |
18 | //TWBR = 10; | ||
17 | } | 19 | } |
18 | 20 | ||
19 | uint8_t i2c_start(uint8_t address) | 21 | uint8_t i2c_start(uint8_t address) |
20 | { | 22 | { |
21 | // reset TWI control register | 23 | // reset TWI control register |
22 | TWCR = 0; | 24 | //TWCR = 0; |
23 | // transmit START condition | 25 | // transmit START condition |
24 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | 26 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); |
25 | // wait for end of transmission | 27 | // wait for end of transmission |
26 | while( !(TWCR & (1<<TWINT)) ); | 28 | while( !(TWCR & (1<<TWINT)) ); |
27 | 29 | ||
28 | // check if the start condition was successfully transmitted | 30 | // check if the start condition was successfully transmitted |
29 | if((TWSR & 0xF8) != TW_START){ return 1; } | 31 | if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; } |
30 | 32 | ||
31 | // load slave address into data register | 33 | // load slave address into data register |
32 | TWDR = address; | 34 | TWDR = address; |
33 | // start transmission of address | 35 | // start transmission of address |
34 | TWCR = (1<<TWINT) | (1<<TWEN); | 36 | TWCR = (1<<TWINT) | (1<<TWEN); |
35 | // wait for end of transmission | 37 | // wait for end of transmission |
36 | while( !(TWCR & (1<<TWINT)) ); | 38 | while( !(TWCR & (1<<TWINT)) ); |
37 | 39 | ||
38 | // check if the device has acknowledged the READ / WRITE mode | 40 | // check if the device has acknowledged the READ / WRITE mode |
39 | uint8_t twst = TW_STATUS & 0xF8; | 41 | uint8_t twst = TW_STATUS & 0xF8; |
40 | if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1; | 42 | if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1; |
41 | 43 | ||
42 | return 0; | 44 | return 0; |
43 | } | 45 | } |
44 | 46 | ||
@@ -50,17 +52,17 @@ uint8_t i2c_write(uint8_t data) | |||
50 | TWCR = (1<<TWINT) | (1<<TWEN); | 52 | TWCR = (1<<TWINT) | (1<<TWEN); |
51 | // wait for end of transmission | 53 | // wait for end of transmission |
52 | while( !(TWCR & (1<<TWINT)) ); | 54 | while( !(TWCR & (1<<TWINT)) ); |
53 | 55 | ||
54 | if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; } | 56 | if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; } |
55 | 57 | ||
56 | return 0; | 58 | return 0; |
57 | } | 59 | } |
58 | 60 | ||
59 | uint8_t i2c_read_ack(void) | 61 | uint8_t i2c_read_ack(void) |
60 | { | 62 | { |
61 | 63 | ||
62 | // start TWI module and acknowledge data after reception | 64 | // start TWI module and acknowledge data after reception |
63 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); | 65 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); |
64 | // wait for end of transmission | 66 | // wait for end of transmission |
65 | while( !(TWCR & (1<<TWINT)) ); | 67 | while( !(TWCR & (1<<TWINT)) ); |
66 | // return received data from TWDR | 68 | // return received data from TWDR |
@@ -69,7 +71,7 @@ uint8_t i2c_read_ack(void) | |||
69 | 71 | ||
70 | uint8_t i2c_read_nack(void) | 72 | uint8_t i2c_read_nack(void) |
71 | { | 73 | { |
72 | 74 | ||
73 | // start receiving without acknowledging reception | 75 | // start receiving without acknowledging reception |
74 | TWCR = (1<<TWINT) | (1<<TWEN); | 76 | TWCR = (1<<TWINT) | (1<<TWEN); |
75 | // wait for end of transmission | 77 | // wait for end of transmission |
@@ -81,29 +83,29 @@ uint8_t i2c_read_nack(void) | |||
81 | uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length) | 83 | uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length) |
82 | { | 84 | { |
83 | if (i2c_start(address | I2C_WRITE)) return 1; | 85 | if (i2c_start(address | I2C_WRITE)) return 1; |
84 | 86 | ||
85 | for (uint16_t i = 0; i < length; i++) | 87 | for (uint16_t i = 0; i < length; i++) |
86 | { | 88 | { |
87 | if (i2c_write(data[i])) return 1; | 89 | if (i2c_write(data[i])) return 1; |
88 | } | 90 | } |
89 | 91 | ||
90 | i2c_stop(); | 92 | i2c_stop(); |
91 | 93 | ||
92 | return 0; | 94 | return 0; |
93 | } | 95 | } |
94 | 96 | ||
95 | uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length) | 97 | uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length) |
96 | { | 98 | { |
97 | if (i2c_start(address | I2C_READ)) return 1; | 99 | if (i2c_start(address | I2C_READ)) return 1; |
98 | 100 | ||
99 | for (uint16_t i = 0; i < (length-1); i++) | 101 | for (uint16_t i = 0; i < (length-1); i++) |
100 | { | 102 | { |
101 | data[i] = i2c_read_ack(); | 103 | data[i] = i2c_read_ack(); |
102 | } | 104 | } |
103 | data[(length-1)] = i2c_read_nack(); | 105 | data[(length-1)] = i2c_read_nack(); |
104 | 106 | ||
105 | i2c_stop(); | 107 | i2c_stop(); |
106 | 108 | ||
107 | return 0; | 109 | return 0; |
108 | } | 110 | } |
109 | 111 | ||
@@ -146,4 +148,6 @@ void i2c_stop(void) | |||
146 | { | 148 | { |
147 | // transmit STOP condition | 149 | // transmit STOP condition |
148 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | 150 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); |
151 | // wait until stop condition is executed and bus released | ||
152 | while(TWCR & (1<<TWSTO)); | ||
149 | } | 153 | } |