blmc/i2c-slave.c

148 lines
3.5 KiB
C
Raw Normal View History

2007-09-20 22:54:11 +02:00
/***************************************************************************
* Copyright (C) 09/2007 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; version 2 of the License, *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "main.h"
#include "blmc.h"
extern struct blmc_ blmc;
2007-09-24 19:43:10 +02:00
#define CMD_WAIT 0x00
#define CMD_GET_INFO 0x10
#define CMD_SET_PWM 0x21
#define CMD_GET_STATUS 0x22
// #define CMD_SET_PARAM 0x23
// #define CMD_GET_PARAM 0x24
#define CMD_BOOT_LOADER 0x2F
const static uint8_t info[16] = "blctrl m8-v1.0";
2007-09-20 22:54:11 +02:00
ISR(TWI_vect)
{
2007-09-24 19:43:10 +02:00
static uint8_t cmd;
static uint8_t bcnt;
2007-09-20 22:54:11 +02:00
switch (TWSR & 0xF8) {
/* SLA + W received, ACK returned -> receive Data and ACK */
case 0x60:
2007-09-24 19:43:10 +02:00
bcnt = 0;
2007-09-20 22:54:11 +02:00
TWCR |= (1<<TWINT) | (1<<TWEA);
break;
/* prev. SLA + W, data received, ACK returned -> receive Data and ACK */
case 0x80:
2007-09-24 19:43:10 +02:00
if (bcnt == 0) {
2007-09-20 22:54:11 +02:00
cmd = TWDR;
2007-09-24 19:43:10 +02:00
switch (cmd) {
case CMD_BOOT_LOADER:
wdt_enable(WDTO_15MS);
2007-09-20 22:54:11 +02:00
2007-09-24 19:43:10 +02:00
case CMD_GET_INFO:
case CMD_SET_PWM:
case CMD_GET_STATUS:
bcnt++;
break;
2007-09-20 22:54:11 +02:00
2007-09-24 19:43:10 +02:00
default:
cmd = CMD_WAIT;
bcnt = 0;
break;
}
2007-09-20 22:54:11 +02:00
2007-09-24 19:43:10 +02:00
} else if (bcnt == 1) {
if (cmd == CMD_SET_PWM)
setpwm(TWDR);
bcnt = 0;
} else {
bcnt = 0;
2007-09-20 22:54:11 +02:00
}
2007-09-24 19:43:10 +02:00
TWCR |= (1<<TWINT) | (1<<TWEA);
2007-09-20 22:54:11 +02:00
break;
/* SLA+R received, ACK returned -> send data */
case 0xA8:
2007-09-24 19:43:10 +02:00
bcnt = 0;
2007-09-20 22:54:11 +02:00
/* prev. SLA+R, data sent, ACK returned -> send data */
case 0xB8:
2007-09-24 19:43:10 +02:00
switch (cmd) {
case CMD_GET_INFO:
TWDR = info[bcnt++];
bcnt %= sizeof(info);
break;
case CMD_GET_STATUS:
switch (bcnt++) {
2007-09-20 22:54:11 +02:00
case 0: TWDR = blmc.pwm - blmc.pwm_limit;
break;
case 1: TWDR = blmc.pwm;
break;
case 2: TWDR = (blmc.rpm >> 8);
break;
case 3: TWDR = (blmc.rpm & 0xFF);
break;
case 4: TWDR = (blmc.current >> 8);
break;
case 5: TWDR = (blmc.current & 0xFF);
break;
case 6: TWDR = (blmc.voltage >> 8);
break;
case 7: TWDR = (blmc.voltage & 0xFF);
2007-09-24 19:43:10 +02:00
bcnt = 0;
break;
default:
bcnt = 0;
2007-09-20 22:54:11 +02:00
break;
}
break;
default:
2007-09-24 19:43:10 +02:00
TWDR = 0xFF;
2007-09-20 22:54:11 +02:00
break;
}
2007-09-24 19:43:10 +02:00
TWCR |= (1<<TWINT) | (1<<TWEA);
2007-09-20 22:54:11 +02:00
break;
/* STOP or repeated START */
case 0xA0:
/* Data transmitted, NACK returned */
case 0xC0:
TWCR |= (1<<TWINT) | (1<<TWEA);
break;
2007-09-24 19:43:10 +02:00
/* failsave -> reset Hardware */
default:
2007-09-20 22:54:11 +02:00
TWCR |= (1<<TWINT) | (1<<TWSTO) | (1<<TWEA);
break;
}
}