You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
6.1 KiB
248 lines
6.1 KiB
/************************************************************
|
|
* reads some digital in and make them readable over i2c bus.
|
|
* register 0 -
|
|
*
|
|
* +-------+
|
|
* (RESET) PC6 -|1 O 28|- PC5 (ADC5/SCL)
|
|
* S3 (RXD) PD0 -|2 27|- PC4 (ADC4/SDA)
|
|
* S2 (TXD) PD1 -|3 26|- PC3 (ADC3)
|
|
* S1 (INT0) PD2 -|4 25|- PC2 (ADC2) S12
|
|
* S10 (INT1) PD3 -|5 24|- PC1 (ADC1) S16
|
|
* S7 (XCK/T0)PD4 -|6 23|- PC0 (ADC0) S15
|
|
* VCC -|7 22|- GND
|
|
* GND -|8 21|- AREF
|
|
* S8 (XTAL2/TOSC2) PB6 -|9 20|- AVCC
|
|
* S9 (XTAL2/TOSC2) PB7 -|10 19|- PB5 (SCK)
|
|
* S4 (T1) PD5 -|11 18|- PB4 (MISO)
|
|
* S5 (AIN0) PD6 -|12 17|- PB3 (MOSI(OC2)
|
|
* S6 (AIN1) PD7 -|13 16|- PB2 (SS/OC1B) S14
|
|
* S11 (ICP1) PB0 -|14 15|- PB1 (OC1A) S13
|
|
* +-------+
|
|
*/
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#include <util/delay.h>
|
|
#include <util/twi.h>
|
|
|
|
#include "eprom.h"
|
|
|
|
#define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
|
|
#define TWCR_NACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
|
|
#define TWCR_RESET TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO);
|
|
|
|
#define I2C_NUM_REGS 8
|
|
#define I2C_DEFAULT_ADDR 0x4F
|
|
#define VERSION 1
|
|
|
|
#define I2C_SREGS_OFFSET 0x20
|
|
|
|
enum {
|
|
I2C_SREG_VERSION = 0,
|
|
I2C_SREG_CMD,
|
|
I2C_SREG_ADDR,
|
|
I2C_SREG_DIOFFDELAY,
|
|
I2C_SREG_DOOFFDELAY,
|
|
|
|
I2C_SREG_MAX
|
|
};
|
|
|
|
enum {
|
|
I2C_CMD_NONE = 0,
|
|
I2C_CMD_EEPROMREAD,
|
|
I2C_CMD_EEPROMWRITE
|
|
};
|
|
|
|
volatile uint8_t i2c_reg;
|
|
volatile uint8_t i2c_system[I2C_SREG_MAX];
|
|
volatile uint8_t i2c_regs[I2C_NUM_REGS];
|
|
|
|
//
|
|
// i2c slave addresse festlegen und interrupts einschalten
|
|
void i2c_slave_init(uint8_t adr) {
|
|
int i;
|
|
|
|
for (i = 0; i < I2C_NUM_REGS; i++) {
|
|
i2c_regs[i] = 0;
|
|
}
|
|
|
|
TWAR = adr << 1;
|
|
TWCR &= ~(1<<TWSTA) | (1<<TWSTO);
|
|
TWCR |= (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
|
|
|
|
i2c_reg = 0x0;
|
|
|
|
sei();
|
|
}
|
|
|
|
ISR (TWI_vect) {
|
|
char data=0;
|
|
|
|
switch (TW_STATUS) {
|
|
case TW_SR_SLA_ACK: // 0x60 Slave Receiver, Slave wurde adressiert
|
|
TWCR_ACK;
|
|
i2c_reg=0xFF;
|
|
break;
|
|
|
|
case TW_SR_DATA_ACK: // 0x80 Slave Receiver, ein Datenbyte wurde empfangen
|
|
data=TWDR;
|
|
if (i2c_reg == 0xFF) {
|
|
if(data < I2C_NUM_REGS || (data >= I2C_SREGS_OFFSET && data < I2C_SREGS_OFFSET+I2C_SREG_MAX)) {
|
|
i2c_reg = data;
|
|
TWCR_ACK;
|
|
}
|
|
else
|
|
TWCR_NACK;
|
|
}
|
|
else {
|
|
if(i2c_reg < I2C_NUM_REGS) {
|
|
i2c_regs[i2c_reg] = data;
|
|
i2c_reg++;
|
|
TWCR_ACK;
|
|
}
|
|
else if (i2c_reg >= I2C_SREGS_OFFSET && i2c_reg < I2C_SREGS_OFFSET+I2C_SREG_MAX) {
|
|
i2c_system[i2c_reg-I2C_SREGS_OFFSET] = data;
|
|
i2c_reg++;
|
|
TWCR_ACK;
|
|
}
|
|
else TWCR_NACK;
|
|
}
|
|
break;
|
|
|
|
case TW_ST_SLA_ACK: //0xA8 Slave wurde im Lesemodus adressiert und hat ein ACK zurückgegeben.
|
|
case TW_ST_DATA_ACK: //0xB8 Slave Transmitter, Daten wurden angefordert
|
|
if (i2c_reg == 0xFF) {
|
|
i2c_reg = 0;
|
|
}
|
|
if (i2c_reg < I2C_NUM_REGS) {
|
|
TWDR = i2c_regs[i2c_reg];
|
|
i2c_reg++;
|
|
TWCR_ACK;
|
|
}
|
|
else if (i2c_reg >= I2C_SREGS_OFFSET && i2c_reg < I2C_SREGS_OFFSET+I2C_SREG_MAX) {
|
|
TWDR = i2c_system[i2c_reg-I2C_SREGS_OFFSET];
|
|
i2c_reg++;
|
|
TWCR_ACK;
|
|
}
|
|
else TWCR_NACK;
|
|
break;
|
|
|
|
case TW_SR_STOP:
|
|
TWCR_ACK;
|
|
break;
|
|
|
|
case TW_ST_DATA_NACK: // 0xC0 Keine Daten mehr gefordert
|
|
case TW_SR_DATA_NACK: // 0x88
|
|
case TW_ST_LAST_DATA: // 0xC8 Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
|
|
default:
|
|
TWCR_RESET;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
int main( void ) {
|
|
long int cnt[16] = { 0 };
|
|
unsigned int i;
|
|
unsigned short int inval = 0;
|
|
unsigned short int temp = 0;
|
|
int offdelay;
|
|
|
|
//
|
|
// read all variables from eeprom
|
|
i2c_system[I2C_SREG_VERSION] = VERSION;
|
|
i2c_system[I2C_SREG_CMD] = 0;
|
|
|
|
i2c_system[I2C_SREG_ADDR] = EEPROM_read(I2C_SREG_ADDR);
|
|
if (i2c_system[I2C_SREG_ADDR] > 0x4f || i2c_system[I2C_SREG_ADDR] < 0x20) {
|
|
i2c_system[I2C_SREG_ADDR] = I2C_DEFAULT_ADDR;
|
|
}
|
|
|
|
i2c_system[I2C_SREG_DIOFFDELAY] = EEPROM_read(I2C_SREG_DIOFFDELAY);
|
|
if (i2c_system[I2C_SREG_DIOFFDELAY] == 0 || i2c_system[I2C_SREG_DIOFFDELAY] == 0xFF) {
|
|
i2c_system[I2C_SREG_DIOFFDELAY] = 0x20;
|
|
}
|
|
|
|
i2c_system[I2C_SREG_DOOFFDELAY] = EEPROM_read(I2C_SREG_DOOFFDELAY);
|
|
if (i2c_system[I2C_SREG_DOOFFDELAY] == 0) {
|
|
i2c_system[I2C_SREG_DOOFFDELAY] = 0xFF;
|
|
}
|
|
|
|
i2c_slave_init (i2c_system[I2C_SREG_ADDR]);
|
|
|
|
//
|
|
// system loop
|
|
while( 1 ) {
|
|
//
|
|
// digital in registers..
|
|
offdelay = i2c_system[I2C_SREG_DIOFFDELAY] << 8;
|
|
|
|
i = 0;
|
|
if (PIND & (1 << 2)) cnt[0] = offdelay;
|
|
if (PIND & (1 << 1)) cnt[1] = offdelay;
|
|
if (PIND & (1 << 0)) cnt[2] = offdelay;
|
|
if (PIND & (1 << 5)) cnt[3] = offdelay;
|
|
if (PIND & (1 << 6)) cnt[4] = offdelay;
|
|
if (PIND & (1 << 7)) cnt[5] = offdelay;
|
|
if (PIND & (1 << 4)) cnt[6] = offdelay;
|
|
if (PINB & (1 << 6)) cnt[7] = offdelay;
|
|
|
|
if (PINB & (1 << 7)) cnt[8] = offdelay;
|
|
if (PIND & (1 << 3)) cnt[9] = offdelay;
|
|
if (PINB & (1 << 0)) cnt[10] = offdelay;
|
|
if (PINC & (1 << 2)) cnt[11] = offdelay;
|
|
if (PINB & (1 << 1)) cnt[12] = offdelay;
|
|
if (PINB & (1 << 2)) cnt[13] = offdelay;
|
|
if (PINC & (1 << 0)) cnt[14] = offdelay;
|
|
if (PINC & (1 << 1)) cnt[15] = offdelay;
|
|
|
|
// all values
|
|
for (i = 0; i < 16; i++) {
|
|
if (cnt[i] == 0) inval &= ~(1 << (i));
|
|
else {
|
|
cnt[i]--;
|
|
inval |= (1 << (i));
|
|
}
|
|
}
|
|
|
|
i2c_regs[0] = (unsigned char) (inval & 0x00FF);
|
|
i2c_regs[1] = (unsigned char) ((inval & 0xFF00) >> 8);
|
|
|
|
temp++;
|
|
i2c_regs[2] = (unsigned char) (temp & 0x00FF);
|
|
i2c_regs[3] = (unsigned char) ((temp & 0xFF00) >> 8);
|
|
|
|
|
|
//
|
|
// system registers
|
|
if (i2c_system[I2C_SREG_CMD] != 0) {
|
|
if (i2c_system[I2C_SREG_CMD] == I2C_CMD_EEPROMREAD) {
|
|
cli();
|
|
i2c_system[I2C_SREG_CMD] = 0;
|
|
for (i = 0; i < I2C_SREG_MAX; i++) {
|
|
i2c_system[i] = EEPROM_read(i);
|
|
}
|
|
sei();
|
|
}
|
|
|
|
if (i2c_system[I2C_SREG_CMD] == I2C_CMD_EEPROMWRITE) {
|
|
cli();
|
|
i2c_system[I2C_SREG_CMD] = 0;
|
|
for (i = 0; i < I2C_SREG_MAX; i++) {
|
|
EEPROM_write(i, i2c_system[i]);
|
|
}
|
|
sei();
|
|
}
|
|
}
|
|
i2c_system[I2C_SREG_CMD] = 0;
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
|