all: bmc.bin
-bmc: bmc.o usart.o i2c.o
+bmc: bmc.o usart.o i2c.o ipmb.o
bmc.bin: bmc
$(OBJCOPY) -j .text -j .data -O binary $^ $@
#include "i2c.h"
#include "bmc.h"
-uint8_t ipmb_csum(unsigned char *buf, int len)
-{
- uint8_t csum = 0x00;
- int i;
-
- for(i = 0; i < len; i++) {
- csum += buf[i];
- }
-
- return -csum;
-}
-
-void decode_bmc_cmd(unsigned char *buf, int len)
-{
- int i;
-
- printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- printf("Connection Header:\n");
- printf("\trs Slave Addr.: 0x%02x\n", buf[0]);
- printf("\tnetFn: 0x%02x, LUN: 0x%02x\n", (buf[1]>>2)&0x3f, (buf[1] & 0x03));
- printf("\tChecksum: 0x%02x (%s)\n", buf[2],
- (buf[2] == ipmb_csum(buf, 2)) ? "OK" : "Wrong");
- printf("Data:\n");
- printf("\trq Slave Addr.: 0x%02x\n", buf[3]);
- printf("\trqSeq: 0x%02x, rqLUN: 0x%02x\n", (buf[4]>>2)&0x3f, (buf[4] & 0x03));
- printf("\tcmd: 0x%02x\n", buf[5]);
- printf("\tData: ");
- for(i = 6; i < (len - 1); i++) {
- printf("0x%02x ", buf[i]);
- }
- printf("\n");
- printf("\tChecksum: 0x%02x (%s)\n", buf[len-1],
- (buf[len-1] == ipmb_csum(buf+3, len-4)) ? "OK" : "Wrong");
- printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
-}
-
int main(void)
{
DDRB = 0xff;
-void decode_bmc_cmd(unsigned char *buf, int len);
#include <avr/interrupt.h>
#include <stdio.h>
#include "i2c.h"
-#include "bmc.h"
+#include "ipmb.h"
#define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
#define TWCR_NACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
PORTC = 0x03;
}
+void i2c_send(unsigned char *buf, int len)
+{
+ uint8_t old_TWCR = TWCR;
+ uint8_t old_SREG = SREG;
+ int i;
+
+ cli();
+
+ TWCR = ((1<<TWINT) | (1<<TWSTA) | (1<<TWEN)); /* Send start */
+
+ while(!(TWCR & (1<<TWINT))) {}
+ if ((TW_STATUS & 0xf8) != TW_START)
+ goto out;
+
+ TWDR = buf[0]; /* SLA_W */
+ TWCR = ((1<<TWINT) | (1<<TWEN));
+
+ while(!(TWCR & (1<<TWINT))) {}
+ if ((TW_STATUS & 0xf8) != TW_MT_SLA_ACK)
+ goto out;
+
+ for(i = 1; i < len; i++) {
+ TWDR = buf[i]; /* Send Data */
+ TWCR = ((1<<TWINT) | (1<<TWEN));
+
+ while(!(TWCR & (1<<TWINT))) {}
+ if ((TW_STATUS & 0xf8) != TW_MT_DATA_ACK)
+ goto out;
+ }
+
+ TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWSTO));
+
+ printf("I2C Data sent 0x%02x\n", TW_STATUS);
+
+
+out:
+ TWDR = 0x00;
+ TWCR = old_TWCR;
+ SREG = old_SREG;
+}
+
ISR (TWI_vect, ISR_BLOCK)
{
switch (TW_STATUS) {
#ifdef DEBUG
printf("I2C: STOP received\n");
#endif
- decode_bmc_cmd((unsigned char*)databuf, pos);
+ decode_ipmb_pkt((unsigned char*)databuf, pos);
pos = 0x00;
TWCR_RESET;
break;
#define BMC_ADDR 0x24
void i2c_init();
+void i2c_send(unsigned char *buf, int len);
--- /dev/null
+#include <stdio.h>
+
+#include "ipmb.h"
+
+uint8_t ipmb_csum(unsigned char *buf, int len)
+{
+ uint8_t csum = 0x00;
+ int i;
+
+ for(i = 0; i < len; i++) {
+ csum += buf[i];
+ }
+
+ return -csum;
+}
+
+void decode_ipmb_pkt(unsigned char *buf, int len)
+{
+ int i;
+ struct ipmb_req req;
+
+ req.rsSA = buf[0];
+ req.netFn = (buf[1]>>2)&0x3f;
+ req.rsLUN = (buf[1] & 0x03);
+ req.rqSA = buf[3];
+ req.rqSEQ = (buf[4]>>2)&0x3f;
+ req.rqLUN = (buf[4] & 0x03);
+ req.cmd = buf[5];
+ req.data = buf+6;
+ req.datalen = len - 6 - 1;
+
+ printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ printf("Connection Header:\n");
+ printf("\trs Slave Addr.: 0x%02x\n", req.rsSA);
+ printf("\tnetFn: 0x%02x, LUN: 0x%02x\n", req.netFn, req.rsLUN);
+ printf("\tChecksum: 0x%02x (%s)\n", buf[2],
+ (buf[2] == ipmb_csum(buf, 2)) ? "OK" : "Wrong");
+ printf("Data:\n");
+ printf("\trq Slave Addr.: 0x%02x\n", req.rqSA);
+ printf("\trqSeq: 0x%02x, rqLUN: 0x%02x\n", req.rqSEQ, req.rqLUN);
+ printf("\tcmd: 0x%02x\n", req.cmd);
+ printf("\tData: ");
+ for(i = 0; i < req.datalen; i++) {
+ printf("0x%02x ", req.data[i]);
+ }
+ printf("\n");
+ printf("\tChecksum: 0x%02x (%s)\n", buf[len-1],
+ (buf[len-1] == ipmb_csum(buf+3, len-4)) ? "OK" : "Wrong");
+ printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+
+ if ((buf[2] != ipmb_csum(buf, 2)) ||
+ (buf[len-1] == ipmb_csum(buf+3, len-4)))
+ return; /* Checksum wrong */
+
+ //i2c_send((unsigned char*)"\x28\x00",1);
+}
--- /dev/null
+struct ipmb_req {
+ uint8_t rsSA;
+ uint8_t netFn;
+ uint8_t rsLUN;
+ uint8_t rqSA;
+ uint8_t rqSEQ;
+ uint8_t rqLUN;
+ uint8_t cmd;
+ unsigned char *data;
+ uint8_t datalen;
+};
+
+void decode_ipmb_pkt(unsigned char *buf, int len);