]> git.zerfleddert.de Git - rsbs2/blame - bmc/i2c.c
I2C master mode implemented and more decoding
[rsbs2] / bmc / i2c.c
CommitLineData
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
11static volatile unsigned char databuf[12];
12static volatile uint8_t pos = 0x00;
13
99e4226b
MG
14void 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
24void 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
59out:
60 TWDR = 0x00;
61 TWCR = old_TWCR;
62 SREG = old_SREG;
63}
64
7f52e040 65ISR (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}
Impressum, Datenschutz