]>
Commit | Line | Data |
---|---|---|
99e4226b MG |
1 | #include <util/twi.h> |
2 | #include <avr/interrupt.h> | |
3 | #include <stdio.h> | |
4 | #include "i2c.h" | |
d5193055 | 5 | #include "ipmb.h" |
99e4226b MG |
6 | |
7 | #define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC); | |
8 | #define TWCR_NACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC); | |
9 | #define TWCR_RESET TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|(0<<TWWC); | |
10 | ||
77ad1a84 MG |
11 | static volatile unsigned char databuf[12]; |
12 | static volatile uint8_t pos = 0x00; | |
13 | ||
99e4226b MG |
14 | void i2c_init() |
15 | { | |
7f52e040 MG |
16 | TWAR = BMC_ADDR & 0xfe; |
17 | TWDR = 0x00; | |
18 | TWCR &= ~((1<<TWSTA) | (1<<TWSTO)); | |
19 | TWCR |= ((1<<TWEA) | (1<<TWEN) | (1<<TWIE)); | |
20 | printf("Status: 0x%02x\n", TW_STATUS); | |
21 | PORTC = 0x03; | |
99e4226b MG |
22 | } |
23 | ||
d5193055 MG |
24 | void i2c_send(unsigned char *buf, int len) |
25 | { | |
26 | uint8_t old_TWCR = TWCR; | |
27 | uint8_t old_SREG = SREG; | |
28 | int i; | |
29 | ||
30 | cli(); | |
31 | ||
32 | TWCR = ((1<<TWINT) | (1<<TWSTA) | (1<<TWEN)); /* Send start */ | |
33 | ||
34 | while(!(TWCR & (1<<TWINT))) {} | |
35 | if ((TW_STATUS & 0xf8) != TW_START) | |
36 | goto out; | |
37 | ||
38 | TWDR = buf[0]; /* SLA_W */ | |
39 | TWCR = ((1<<TWINT) | (1<<TWEN)); | |
40 | ||
41 | while(!(TWCR & (1<<TWINT))) {} | |
42 | if ((TW_STATUS & 0xf8) != TW_MT_SLA_ACK) | |
43 | goto out; | |
44 | ||
45 | for(i = 1; i < len; i++) { | |
46 | TWDR = buf[i]; /* Send Data */ | |
47 | TWCR = ((1<<TWINT) | (1<<TWEN)); | |
48 | ||
49 | while(!(TWCR & (1<<TWINT))) {} | |
50 | if ((TW_STATUS & 0xf8) != TW_MT_DATA_ACK) | |
51 | goto out; | |
52 | } | |
53 | ||
54 | TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWSTO)); | |
55 | ||
56 | printf("I2C Data sent 0x%02x\n", TW_STATUS); | |
57 | ||
58 | ||
59 | out: | |
60 | TWDR = 0x00; | |
61 | TWCR = old_TWCR; | |
62 | SREG = old_SREG; | |
63 | } | |
64 | ||
7f52e040 | 65 | ISR (TWI_vect, ISR_BLOCK) |
99e4226b | 66 | { |
99e4226b | 67 | switch (TW_STATUS) { |
77ad1a84 MG |
68 | case TW_SR_SLA_ACK: |
69 | #ifdef DEBUG | |
70 | printf("I2C: Slave 0x%02x adressed\n", TWDR); | |
71 | #endif | |
72 | pos = 0x00; | |
20ef0f39 MG |
73 | databuf[pos] = TWDR; |
74 | pos++; | |
77ad1a84 MG |
75 | TWCR_ACK; |
76 | break; | |
77 | ||
78 | case TW_SR_DATA_ACK: | |
79 | #ifdef DEBUG | |
80 | printf("I2C: Data received: 0x%02x\n", TWDR); | |
81 | #endif | |
82 | databuf[pos] = TWDR; | |
83 | pos++; | |
84 | TWCR_ACK; | |
85 | break; | |
86 | ||
87 | case TW_SR_STOP: | |
88 | #ifdef DEBUG | |
89 | printf("I2C: STOP received\n"); | |
90 | #endif | |
d5193055 | 91 | decode_ipmb_pkt((unsigned char*)databuf, pos); |
77ad1a84 MG |
92 | pos = 0x00; |
93 | TWCR_RESET; | |
94 | break; | |
95 | ||
77ad1a84 MG |
96 | default: |
97 | printf("I2C: Unimplemented status 0x%02x\n", TW_STATUS); | |
98 | TWCR_RESET; | |
99 | break; | |
99e4226b MG |
100 | } |
101 | } |