mirror of
https://github.com/KostyaSha/arduino-iebus.git
synced 2025-06-20 13:56:09 +00:00
init
This commit is contained in:
parent
42182efc61
commit
d947c58703
141
arduino/AVCLan_mini/AVCLan_mini.ino
Normal file
141
arduino/AVCLan_mini/AVCLan_mini.ino
Normal file
@ -0,0 +1,141 @@
|
||||
|
||||
#include <AVCLanDrv.h>
|
||||
#include <BuffSerial.h>
|
||||
#include <config.h>
|
||||
|
||||
|
||||
int ledPin = 13; // LED connected to digital pin 13
|
||||
AVCLanDrv avclan;
|
||||
bool first;
|
||||
byte t;
|
||||
byte count;
|
||||
|
||||
void setup(){
|
||||
pinMode(ledPin, OUTPUT); // sets the digital pin as output
|
||||
bSerial.begin(250000);
|
||||
avclan.begin();
|
||||
bSerial.println("AVCLan");
|
||||
first = true;
|
||||
}
|
||||
|
||||
void loop(){
|
||||
|
||||
|
||||
if (INPUT_IS_SET){
|
||||
// LedOn();
|
||||
byte res = avclan.readMessage();
|
||||
if (!res){
|
||||
avclan.printMessage(true);
|
||||
}else{
|
||||
bSerial.print("R");
|
||||
bSerial.printHex4(res);
|
||||
bSerial.println();
|
||||
while (!avclan.isAvcBusFree());
|
||||
}
|
||||
// LedOff();
|
||||
}else{
|
||||
if (first){
|
||||
first = false;
|
||||
avclan.deviceAddress = 0x240;
|
||||
avclan.broadcast = AVC_MSG_BROADCAST;
|
||||
avclan.masterAddress = 0x0360;
|
||||
avclan.slaveAddress = 0x01FF;
|
||||
avclan.dataSize = 0x04;
|
||||
avclan.message[0] = 0x01;
|
||||
avclan.message[1] = 0x11;
|
||||
avclan.message[2] = 0x13;
|
||||
avclan.message[3] = 0x63;
|
||||
// byte res = avclan.sendMessage();
|
||||
// if (!res){
|
||||
// avclan.printMessage(false);
|
||||
// }else{
|
||||
// bSerial.print("W");
|
||||
// bSerial.printHex4(res);
|
||||
// bSerial.println();
|
||||
// }
|
||||
}
|
||||
}
|
||||
if (bSerial.rxEnabled()) {
|
||||
cbi(UCSR0B, RXCIE0); // disable RX complete interrupt
|
||||
uint8_t readkey = bSerial.rxRead();
|
||||
|
||||
switch (readkey){
|
||||
case 'P': // print config
|
||||
bSerial.print("Overflow: ");
|
||||
bSerial.printHex8(bSerial.txOverflow >> 8);
|
||||
bSerial.printHex8(bSerial.txOverflow);
|
||||
bSerial.println();
|
||||
break;
|
||||
case 'M':
|
||||
count = 0;
|
||||
while(1){
|
||||
while (INPUT_IS_SET);
|
||||
uint8_t oldSREG = SREG;
|
||||
cli(); // disable interrupts
|
||||
while (INPUT_IS_CLEAR);
|
||||
TCNT2 = 0;
|
||||
while (INPUT_IS_SET){
|
||||
t = TCNT2;
|
||||
if (t > 0xF0) break;
|
||||
};
|
||||
t = t / 2;
|
||||
SREG = oldSREG;
|
||||
bSerial.printDec(t);
|
||||
bSerial.println();
|
||||
count++;
|
||||
if (count > 30){
|
||||
delay(300);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
bSerial.println("S");
|
||||
sendMess();
|
||||
break;
|
||||
case 'H':
|
||||
bSerial.println("H set");
|
||||
AVC_OUT_EN;
|
||||
OUTPUT_SET_1;
|
||||
break;
|
||||
case 'L':
|
||||
bSerial.println("L set");
|
||||
AVC_OUT_EN;
|
||||
OUTPUT_SET_0;
|
||||
break;
|
||||
case 'D':
|
||||
bSerial.println("Out dis");
|
||||
AVC_OUT_DIS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendMess(){
|
||||
avclan.deviceAddress = 0x360;
|
||||
avclan.broadcast = AVC_MSG_NORMAL;
|
||||
avclan.masterAddress = 0x0360;
|
||||
avclan.slaveAddress = 0x0140;
|
||||
avclan.dataSize = 0x05;
|
||||
avclan.message[0] = 0x00;
|
||||
avclan.message[1] = 0x01;
|
||||
avclan.message[2] = 0x12;
|
||||
avclan.message[2] = 0x10;
|
||||
avclan.message[3] = 0x63;
|
||||
byte res = avclan.sendMessage();
|
||||
if (!res){
|
||||
avclan.printMessage(false);
|
||||
}else{
|
||||
bSerial.print("W");
|
||||
bSerial.printHex4(res);
|
||||
bSerial.println();
|
||||
}
|
||||
}
|
||||
|
||||
void LedOn(){
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
|
||||
void LedOff(){
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
2
arduino/README.md
Normal file
2
arduino/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
Sources from http://compcar.ru/forum/showthread.php?t=3959
|
||||
|
447
arduino/libraries/AVCLanDrv/AVCLanDrv.cpp
Normal file
447
arduino/libraries/AVCLanDrv/AVCLanDrv.cpp
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
AVCLanDrv.cpp v.01 - AVCLan Library for 'duino / Wiring
|
||||
Created by Kochetkov Aleksey, 30.06.2009
|
||||
*/
|
||||
|
||||
#include "AVCLanDrv.h"
|
||||
#include "BuffSerial.h"
|
||||
|
||||
// AVCLan driver & timer2 init,
|
||||
void AVCLanDrv::begin (){
|
||||
// AVCLan TX+/TX- read line INPUT
|
||||
cbi(DATAIN_DDR, DATAIN);
|
||||
#ifdef AVCLAN_ST485
|
||||
sbi(DATAIN_PORT, DATAIN);
|
||||
#else
|
||||
cbi(DATAIN_PORT, DATAIN);
|
||||
#endif
|
||||
|
||||
// AVCLan TX+/TX- write line OUTPUT
|
||||
#ifdef AVCLAN_RESISTOR
|
||||
cbi(DATAOUT_DDR, DATAOUT);
|
||||
cbi(DATAOUT_PORT, DATAOUT);
|
||||
cbi(ADCSRB, ACME); // Analog Comparator Multiplexer Enable - NO
|
||||
cbi(ACSR, ACIS1); // Analog Comparator Interrupt Mode Select
|
||||
cbi(ACSR, ACIS0); // Comparator Interrupt on Output Toggle
|
||||
cbi(ACSR, ACD); // Analog Comparator Disbale - NO
|
||||
#else
|
||||
sbi(DATAOUT_DDR, DATAOUT);
|
||||
sbi(OUTEN_DDR, OUTEN);
|
||||
AVC_OUT_DIS;
|
||||
OUTPUT_SET_0;
|
||||
#endif
|
||||
// timer2 setup, prescaler factor - 8
|
||||
#if defined(__AVR_ATmega8__)
|
||||
// ASSR=0x00;
|
||||
TCCR2=0x02;
|
||||
// TCNT2=0x00;
|
||||
// OCR2=0x00;
|
||||
#else // ATMega168
|
||||
// ASSR=0x00;
|
||||
// TCCR2A=0x00;
|
||||
TCCR2B=0x02;
|
||||
// TCNT2=0x00;
|
||||
// OCR2A=0x00;
|
||||
// OCR2B=0x00;
|
||||
#endif
|
||||
deviceAddress = 0x0000;
|
||||
}
|
||||
|
||||
// Reads specified number of bits from the AVCLan.
|
||||
// nbBits (byte) -> Number of bits to read.
|
||||
// Return (word) -> Data value read.
|
||||
word AVCLanDrv::readBits (byte nbBits){
|
||||
word data = 0;
|
||||
_parityBit = 0;
|
||||
|
||||
while (nbBits-- > 0){
|
||||
// Insert new bit
|
||||
data <<= 1;
|
||||
// Wait until rising edge of new bit.
|
||||
while (INPUT_IS_CLEAR){
|
||||
// Reset watchdog.
|
||||
//wdt_reset();
|
||||
}
|
||||
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 0;
|
||||
// Wait until falling edge.
|
||||
while (INPUT_IS_SET);
|
||||
// Compare half way between a '1' (20 us) and a '0' (32 us ): 32 - (32 - 20) /2 = 26 us
|
||||
if (TCNT2 < AVC_BIT_0_HOLD_ON_MIN_LENGTH){
|
||||
// Set new bit.
|
||||
data |= 0x0001;
|
||||
// Adjust parity.
|
||||
_parityBit = ! _parityBit;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// Read incoming messages on the AVCLan.
|
||||
// Return true if success.
|
||||
byte AVCLanDrv::readMessage (){
|
||||
uint8_t t = 0;
|
||||
uint8_t oldSREG = SREG;
|
||||
cli(); // disable interrupts
|
||||
|
||||
// Start bit.
|
||||
while (INPUT_IS_CLEAR);
|
||||
TCCR2B=0x03; // prescaler 32
|
||||
TCNT2 = 0;
|
||||
// Wait until falling edge.
|
||||
while (INPUT_IS_SET){
|
||||
t = TCNT2;
|
||||
if (t > 0xFF) {
|
||||
SREG = oldSREG;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
TCCR2B=0x02; // prescaler 8
|
||||
|
||||
if (t < AVC_START_BIT_HOLD_ON_MIN_LENGTH){
|
||||
//if (t < 0x16){
|
||||
SREG = oldSREG;
|
||||
return 2;
|
||||
}
|
||||
|
||||
broadcast = readBits(1);
|
||||
|
||||
masterAddress = readBits(12);
|
||||
bool p = _parityBit;
|
||||
if (p != readBits(1)){
|
||||
SREG = oldSREG;
|
||||
return 3;
|
||||
}
|
||||
|
||||
slaveAddress = readBits(12);
|
||||
p = _parityBit;
|
||||
if (p != readBits(1)){
|
||||
SREG = oldSREG;
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool forMe = ( slaveAddress == deviceAddress );
|
||||
|
||||
if (forMe){
|
||||
// Send ACK.
|
||||
send1BitWord(0);
|
||||
}else{
|
||||
readBits(1);
|
||||
}
|
||||
|
||||
// Control
|
||||
readBits(4);
|
||||
p = _parityBit;
|
||||
if (p != readBits(1)){
|
||||
SREG = oldSREG;
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (forMe){
|
||||
// Send ACK.
|
||||
send1BitWord(0);
|
||||
}else{
|
||||
readBits(1);
|
||||
}
|
||||
|
||||
dataSize = readBits(8);
|
||||
p = _parityBit;
|
||||
if (p != readBits(1)){
|
||||
SREG = oldSREG;
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (forMe){
|
||||
// Send ACK.
|
||||
send1BitWord(0);
|
||||
}else{
|
||||
readBits(1);
|
||||
}
|
||||
if (dataSize > AVC_MAXMSGLEN){
|
||||
SREG = oldSREG;
|
||||
return 7;
|
||||
}
|
||||
byte i;
|
||||
for (i = 0; i < dataSize; i++ ){
|
||||
message[i] = readBits(8);
|
||||
p = _parityBit;
|
||||
if (p != readBits(1)){
|
||||
SREG = oldSREG;
|
||||
return 8;
|
||||
}
|
||||
|
||||
if (forMe){
|
||||
// Send ACK.
|
||||
send1BitWord(0);
|
||||
}else{
|
||||
readBits(1);
|
||||
}
|
||||
}
|
||||
SREG = oldSREG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send a start bit to the AVCLan
|
||||
void AVCLanDrv::sendStartBit (){
|
||||
// Reset timer to measure bit length.
|
||||
TCCR2B=0x03; // prescaler 32
|
||||
TCNT2 = 0;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
// Pulse level high duration.
|
||||
while ( TCNT2 < AVC_START_BIT_HOLD_ON_LENGTH );
|
||||
OUTPUT_SET_0;
|
||||
|
||||
// Pulse level low duration until ~185 us.
|
||||
while ( TCNT2 < AVC_START_BIT_LENGTH );
|
||||
TCCR2B=0x02; // prescaler 8
|
||||
|
||||
}
|
||||
|
||||
// Send a 1 bit word to the AVCLan
|
||||
void AVCLanDrv::send1BitWord (bool data){
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 0;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
if (data){
|
||||
while (TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH);
|
||||
}else{
|
||||
while (TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH);
|
||||
}
|
||||
|
||||
OUTPUT_SET_0;
|
||||
while (TCNT2 < AVC_NORMAL_BIT_LENGTH);
|
||||
}
|
||||
|
||||
// Send a 4 bit word to the AVCLan
|
||||
void AVCLanDrv::send4BitWord (byte data){
|
||||
_parityBit = 0;
|
||||
|
||||
// Most significant bit out first.
|
||||
for ( char nbBits = 0; nbBits < 4; nbBits++ ){
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 2;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
if (data & 0x8){
|
||||
// Adjust parity.
|
||||
_parityBit = ! _parityBit;
|
||||
while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH );
|
||||
}else{
|
||||
while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH );
|
||||
}
|
||||
|
||||
OUTPUT_SET_0;
|
||||
// Hold output low until end of bit.
|
||||
while ( TCNT2 < AVC_NORMAL_BIT_LENGTH );
|
||||
|
||||
// Fetch next bit.
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a 8 bit word to the AVCLan
|
||||
void AVCLanDrv::send8BitWord (byte data){
|
||||
_parityBit = 0;
|
||||
|
||||
// Most significant bit out first.
|
||||
for ( char nbBits = 0; nbBits < 8; nbBits++ ){
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 2;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
if (data & 0x80){
|
||||
// Adjust parity.
|
||||
_parityBit = ! _parityBit;
|
||||
while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH );
|
||||
}else{
|
||||
while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH );
|
||||
}
|
||||
|
||||
OUTPUT_SET_0;
|
||||
// Hold output low until end of bit.
|
||||
while ( TCNT2 < AVC_NORMAL_BIT_LENGTH );
|
||||
|
||||
// Fetch next bit.
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a 12 bit word to the AVCLan
|
||||
void AVCLanDrv::send12BitWord (word data){
|
||||
_parityBit = 0;
|
||||
|
||||
// Most significant bit out first.
|
||||
for ( char nbBits = 0; nbBits < 12; nbBits++ ){
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 2;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
if (data & 0x0800){
|
||||
// Adjust parity.
|
||||
_parityBit = ! _parityBit;
|
||||
while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH );
|
||||
}else{
|
||||
while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH );
|
||||
}
|
||||
|
||||
OUTPUT_SET_0;
|
||||
// Hold output low until end of bit.
|
||||
while ( TCNT2 < AVC_NORMAL_BIT_LENGTH );
|
||||
|
||||
// Fetch next bit.
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// determine whether the bus is free (no tx/rx).
|
||||
// return TRUE is bus is free.
|
||||
bool AVCLanDrv::isAvcBusFree (void){
|
||||
// Reset timer.
|
||||
TCNT2 = 0;
|
||||
|
||||
while (INPUT_IS_CLEAR){
|
||||
// We assume the bus is free if anything happens for the length of 1 bit.
|
||||
if (TCNT2 > AVC_NORMAL_BIT_LENGTH){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// reads the acknowledge bit the AVCLan
|
||||
// return TRUE if ack detected else FALSE.
|
||||
bool AVCLanDrv::readAcknowledge (void){
|
||||
// The acknowledge pattern is very tricky: the sender shall drive the bus for the equivalent
|
||||
// of a bit '1' (20 us) then release the bus and listen. At this point the target shall have
|
||||
// taken over the bus maintaining the pulse until the equivalent of a bit '0' (32 us) is formed.
|
||||
|
||||
// Reset timer to measure bit length.
|
||||
TCNT2 = 0;
|
||||
OUTPUT_SET_1;
|
||||
|
||||
// Generate bit '0'.
|
||||
while (TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH);
|
||||
OUTPUT_SET_0;
|
||||
|
||||
AVC_OUT_DIS;
|
||||
|
||||
while (TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH + AVC_1U_LENGTH);
|
||||
// Measure final resulting bit.
|
||||
while ( INPUT_IS_SET );
|
||||
|
||||
// Sample half-way through bit '0' (26 us) to detect whether the target is acknowledging.
|
||||
if (TCNT2 > AVC_BIT_0_HOLD_ON_MIN_LENGTH){
|
||||
// Slave is acknowledging (ack = 0). Wait until end of ack bit.
|
||||
while (INPUT_IS_SET );
|
||||
AVC_OUT_EN;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No sign of life on the bus.
|
||||
return false;
|
||||
}
|
||||
|
||||
// sends ack bit if I am broadcasting otherwise wait and return received ack bit.
|
||||
// return FALSE if ack bit not detected.
|
||||
bool AVCLanDrv::handleAcknowledge (void){
|
||||
if (broadcast == AVC_MSG_BROADCAST){
|
||||
// Acknowledge.
|
||||
send1BitWord(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return acknowledge bit.
|
||||
return readAcknowledge();
|
||||
}
|
||||
|
||||
// sends the message in global registers on the AVC LAN bus.
|
||||
// return TRUE if successful else FALSE.
|
||||
byte AVCLanDrv::sendMessage (void){
|
||||
uint8_t oldSREG = SREG;
|
||||
cli(); // disable interrupts
|
||||
while (!isAvcBusFree());
|
||||
|
||||
AVC_OUT_EN;
|
||||
|
||||
// Send start bit.
|
||||
sendStartBit();
|
||||
|
||||
// Broadcast bit.
|
||||
send1BitWord(broadcast);
|
||||
|
||||
// Master address = me.
|
||||
send12BitWord(masterAddress);
|
||||
send1BitWord(_parityBit);
|
||||
|
||||
// Slave address = head unit (HU).
|
||||
send12BitWord(slaveAddress);
|
||||
send1BitWord(_parityBit);
|
||||
if (!handleAcknowledge()){
|
||||
AVC_OUT_DIS;
|
||||
SREG = oldSREG;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Control flag + parity.
|
||||
send4BitWord(AVC_CONTROL_FLAGS);
|
||||
send1BitWord(_parityBit);
|
||||
if (!handleAcknowledge()){
|
||||
AVC_OUT_DIS;
|
||||
SREG = oldSREG;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Data length + parity.
|
||||
send8BitWord(dataSize);
|
||||
send1BitWord(_parityBit);
|
||||
if (!handleAcknowledge()){
|
||||
AVC_OUT_DIS;
|
||||
SREG = oldSREG;
|
||||
return 3;
|
||||
}
|
||||
|
||||
for (byte i = 0; i < dataSize; i++){
|
||||
send8BitWord(message[i]);
|
||||
send1BitWord(_parityBit);
|
||||
if (!handleAcknowledge()){
|
||||
AVC_OUT_DIS;
|
||||
SREG = oldSREG;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
AVC_OUT_DIS;
|
||||
SREG = oldSREG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// print message to serial
|
||||
void AVCLanDrv::printMessage(bool incoming){
|
||||
if (incoming){
|
||||
bSerial.print("< ");
|
||||
}else{
|
||||
bSerial.print("> ");
|
||||
}
|
||||
if (broadcast == AVC_MSG_BROADCAST){
|
||||
bSerial.print("b ");
|
||||
}else{
|
||||
bSerial.print("d ");
|
||||
}
|
||||
bSerial.printHex4(masterAddress >> 8);
|
||||
bSerial.printHex8(masterAddress);
|
||||
bSerial.print(" ");
|
||||
|
||||
bSerial.printHex4(slaveAddress >> 8);
|
||||
bSerial.printHex8(slaveAddress);
|
||||
bSerial.print(" ");
|
||||
bSerial.printHex8(dataSize);
|
||||
|
||||
for (byte i = 0; i < dataSize; i++){
|
||||
bSerial.printHex8(message[i]);
|
||||
}
|
||||
bSerial.println();
|
||||
|
||||
}
|
108
arduino/libraries/AVCLanDrv/AVCLanDrv.h
Normal file
108
arduino/libraries/AVCLanDrv/AVCLanDrv.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
AVCLanDrv.h v.01 - AVCLan Library for 'duino / Wiring
|
||||
Created by Kochetkov Aleksey, 30.06.2009
|
||||
*/
|
||||
|
||||
#ifndef AVCLanDrv_h
|
||||
#define AVCLanDrv_h
|
||||
|
||||
#include "WProgram.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef AVCLAN_RESISTOR
|
||||
// avclan driver on resistor
|
||||
#define INPUT_IS_SET (ACSR & _BV(ACO))
|
||||
#define INPUT_IS_CLEAR (!(ACSR & _BV(ACO)))
|
||||
#define OUTPUT_SET_1 sbi(PORTD, DATAOUT);
|
||||
#define OUTPUT_SET_0 cbi(PORTD, DATAOUT);
|
||||
#define AVC_OUT_EN sbi(PORTD, DATAOUT); sbi(DDRD, DATAOUT); sbi(DDRD, DATAIN); sbi(ACSR, ACD);
|
||||
#define AVC_OUT_DIS cbi(PORTD, DATAOUT); cbi(DDRD, DATAOUT); cbi(DDRD, DATAIN); cbi(ACSR, ACD);
|
||||
#else
|
||||
#ifdef AVCLAN_ST485
|
||||
// avclan driver on ST485
|
||||
#define INPUT_IS_SET (bit_is_clear(DATAIN_PIN, DATAIN))
|
||||
#define INPUT_IS_CLEAR (bit_is_set(DATAIN_PIN, DATAIN))
|
||||
#define OUTPUT_SET_1 (cbi(DATAOUT_PORT, DATAOUT));
|
||||
#define OUTPUT_SET_0 (sbi(DATAOUT_PORT, DATAOUT));
|
||||
#define AVC_OUT_EN (sbi(OUTEN_PORT, OUTEN));;
|
||||
#define AVC_OUT_DIS (cbi(OUTEN_PORT, OUTEN));;
|
||||
#else
|
||||
//avclan driver on PCA82C250 & LM239N
|
||||
#define INPUT_IS_SET (bit_is_set(DATAIN_PIN, DATAIN))
|
||||
#define INPUT_IS_CLEAR (bit_is_clear(DATAIN_PIN, DATAIN))
|
||||
#define OUT_SET_1 (cbi(DATAOUT_PORT, DATAOUT));
|
||||
#define OUT_SET_0 (sbi(DATAOUT_PORT, DATAOUT));
|
||||
#define AVC_OUT_EN ;
|
||||
#define AVC_OUT_DIS ;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define AVC_NORMAL_BIT_LENGTH 0x4A // 37 * (F_CPU / 1000000L / 8)
|
||||
#define AVC_BIT_1_HOLD_ON_LENGTH 0x28 // 20 uS * (F_CPU / 1000000L / 8)
|
||||
#define AVC_BIT_0_HOLD_ON_LENGTH 0x40 // 32 uS * (F_CPU / 1000000L / 8)
|
||||
//#define AVC_BIT_0_HOLD_ON_MIN_LENGTH 0x34 // 26 uS * (F_CPU / 1000000L / 8) Compare half way between a '1' (20 us) and a '0' (32 us ): 32 - (32 - 20) /2 = 26 us
|
||||
#define AVC_BIT_0_HOLD_ON_MIN_LENGTH 0x3C // 30 uS * (F_CPU / 1000000L / 8) Compare half way between a '1' (20 us) and a '0' (32 us ): 32 - (32 - 20) /2 = 26 us
|
||||
#define AVC_START_BIT_LENGTH 0x5D // 186 uS * (F_CPU / 1000000L / 32) , prescaler 32
|
||||
#define AVC_START_BIT_HOLD_ON_LENGTH 0x54 // 168 uS * (F_CPU / 1000000L / 32) prescaler 32
|
||||
#define AVC_START_BIT_HOLD_ON_MIN_LENGTH 0x16 // 44 uS * (F_CPU / 1000000L / 32) grater that AVC_NORMAL_BIT_LENGTH, prescaler 32
|
||||
#define AVC_1U_LENGTH 0x02 // 1 uS * (F_CPU / 1000000L / 8)
|
||||
|
||||
#define AVC_MAXMSGLEN 32
|
||||
#define AVC_CONTROL_FLAGS 0xF
|
||||
|
||||
typedef enum
|
||||
{ // No this is not a mistake, broadcast = 0!
|
||||
AVC_MSG_NORMAL = 1,
|
||||
AVC_MSG_BROADCAST = 0
|
||||
} AvcTransmissionMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ACT_NONE,
|
||||
|
||||
// ACT_AUX_IN_USE,
|
||||
// ACT_TUNER_IN_USE,
|
||||
// ACT_TAPE_IN_USE,
|
||||
// ACT_CD_IN_USE,
|
||||
|
||||
// ACT_EJECT_CD,
|
||||
// ACT_NO_CD,
|
||||
|
||||
// ACT_STATUS,
|
||||
// ACT_REGISTER,
|
||||
// ACT_INIT,
|
||||
// ACT_CHECK
|
||||
} AvcActionID;
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
class AVCLanDrv{
|
||||
public:
|
||||
bool broadcast;
|
||||
word masterAddress;
|
||||
word slaveAddress;
|
||||
word deviceAddress;
|
||||
byte dataSize;
|
||||
byte message[AVC_MAXMSGLEN];
|
||||
void begin ();
|
||||
byte readMessage ();
|
||||
byte sendMessage (void);
|
||||
void printMessage(bool incoming);
|
||||
bool isAvcBusFree (void);
|
||||
private:
|
||||
bool _parityBit;
|
||||
word readBits (byte nbBits);
|
||||
void sendStartBit (void);
|
||||
void send1BitWord (bool data);
|
||||
void send4BitWord (byte data);
|
||||
void send8BitWord (byte data);
|
||||
void send12BitWord (word data);
|
||||
bool readAcknowledge (void);
|
||||
bool handleAcknowledge (void);
|
||||
};
|
||||
#endif
|
31
arduino/libraries/AVCLanDrv/WProgram.h
Normal file
31
arduino/libraries/AVCLanDrv/WProgram.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef WProgram_h
|
||||
#define WProgram_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef BuffSerial_h
|
||||
#include "HardwareSerial.h"
|
||||
#endif
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
long random(long, long);
|
||||
void randomSeed(unsigned int);
|
||||
long map(long, long, long, long, long);
|
||||
#endif
|
||||
|
||||
#endif
|
43
arduino/libraries/AVCLanDrv/config.h
Normal file
43
arduino/libraries/AVCLanDrv/config.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
config.h - AVCLan driver config
|
||||
Created by Kochetkov Aleksey, 30.06.2009
|
||||
*/
|
||||
|
||||
// type of AVCLan hardwire driver
|
||||
#define AVCLAN_ST485
|
||||
//#define AVCLAN_PCA82C250
|
||||
//#define AVCLAN_RESISTOR
|
||||
|
||||
#ifdef AVCLAN_ST485
|
||||
// define out pin (pin 11 arduino) for ST485
|
||||
#define DATAOUT_DDR DDRB
|
||||
#define DATAOUT_PORT PORTB
|
||||
#define DATAOUT_PIN PINB
|
||||
#define DATAOUT 3
|
||||
|
||||
// define out control pin (pin 10 arduino) for ST485
|
||||
#define OUTEN_DDR DDRB
|
||||
#define OUTEN_PORT PORTB
|
||||
#define OUTEN_PIN PINB
|
||||
#define OUTEN 2
|
||||
|
||||
// define in pin (pin 9 arduino) for ST485
|
||||
#define DATAIN_DDR DDRB
|
||||
#define DATAIN_PORT PORTB
|
||||
#define DATAIN_PIN PINB
|
||||
#define DATAIN 1
|
||||
#endif
|
||||
|
||||
// define out pin (pin 6 arduino) for AVCLAN_RESISTOR
|
||||
// #define DATAOUT_DDR DDRD
|
||||
// #define DATAOUT_PORT PORTD
|
||||
// #define DATAOUT_PIN PIND
|
||||
// #define DATAOUT 6
|
||||
|
||||
// define in pin (pin 7 arduino) for AVCLAN_RESISTOR
|
||||
// #define DATAIN_DDR DDRD
|
||||
// #define DATAIN_PORT PORTD
|
||||
// #define DATAIN_PIN PIND
|
||||
// #define DATAIN 7
|
||||
|
||||
|
163
arduino/libraries/BuffSerial/BuffSerial.cpp
Normal file
163
arduino/libraries/BuffSerial/BuffSerial.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
BuffSerial.cpp v.01 - serial with transmit buffer library for Wiring
|
||||
Created by Kochetkov Aleksey, 03.07.2009
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include "BuffSerial.h"
|
||||
|
||||
// serial init
|
||||
void BuffSerial::begin(long speed){
|
||||
#if defined(__AVR_ATmega8__)
|
||||
UCSRB = _BV(RXCIE) | _BV(RXEN) | _BV(TXCIE) | _BV(TXEN); // enable rx, tx inerrputs
|
||||
UBRRH = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8; // usart speed
|
||||
UBRRL = ((F_CPU / 16 + speed / 2) / speed - 1);
|
||||
#else
|
||||
UCSR0B = (_BV(RXCIE0) | _BV(RXEN0) | _BV(TXCIE0) | _BV(TXEN0)); // enable rx, tx inerrputs
|
||||
UBRR0H = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8; // usart speed
|
||||
UBRR0L = ((F_CPU / 16 + speed / 2) / speed - 1);
|
||||
#endif
|
||||
rxBegin = rxEnd = 0;
|
||||
txBegin = txEnd = txOverflow = 0;
|
||||
txFull = 0;
|
||||
}
|
||||
|
||||
//USART Rx Complete
|
||||
#if defined(__AVR_ATmega8__)
|
||||
SIGNAL(SIG_UART_RECV)
|
||||
#else
|
||||
SIGNAL(USART_RX_vect)
|
||||
#endif
|
||||
{
|
||||
#if defined(__AVR_ATmega8__)
|
||||
bSerial.rxBuffer[bSerial.rxEnd] = UDR;
|
||||
#else
|
||||
bSerial.rxBuffer[bSerial.rxEnd] = UDR0;
|
||||
#endif
|
||||
if (bSerial.rxEnd < RX_BUFF_SIZE) bSerial.rxEnd++;
|
||||
}
|
||||
|
||||
//USART Tx Complete
|
||||
#if defined(__AVR_ATmega8__)
|
||||
SIGNAL(SIG_UART_TRANS)
|
||||
#else
|
||||
SIGNAL(USART_TX_vect)
|
||||
#endif
|
||||
{
|
||||
if (bSerial.txEnd != bSerial.txBegin || bSerial.txFull != 0){
|
||||
#if defined(__AVR_ATmega8__)
|
||||
UDR = bSerial.txBuffer[bSerial.txBegin]; // Send buffer
|
||||
#else
|
||||
UDR0 = bSerial.txBuffer[bSerial.txBegin]; // Send buffer
|
||||
#endif
|
||||
bSerial.txFull = 0;
|
||||
bSerial.txBegin++;
|
||||
if (bSerial.txBegin == TX_BUFF_SIZE) bSerial.txBegin = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// send byte to serial or buffer if bisy
|
||||
void BuffSerial::sendByte(uint8_t data){
|
||||
if (txFull){
|
||||
txOverflow++;
|
||||
}else{
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
#if defined(__AVR_ATmega8__)
|
||||
if (txEnd != txBegin || (UCSRA & _BV(UDRE)) == 0){
|
||||
#else
|
||||
if (txEnd != txBegin || (UCSR0A & _BV(UDRE0)) == 0){
|
||||
#endif
|
||||
txBuffer[txEnd] = data;
|
||||
txEnd++;
|
||||
if (txEnd == TX_BUFF_SIZE) txEnd = 0;
|
||||
if (txEnd == txBegin) txFull = 1; // buffer overflow
|
||||
}else{
|
||||
#if defined(__AVR_ATmega8__)
|
||||
UDR = data;
|
||||
#else
|
||||
UDR0 = data;
|
||||
#endif
|
||||
}
|
||||
SREG = oldSREG;
|
||||
}
|
||||
}
|
||||
|
||||
// print string
|
||||
void BuffSerial::print(const char *pBuf){
|
||||
while (*pBuf) {
|
||||
sendByte(*pBuf++);
|
||||
}
|
||||
}
|
||||
|
||||
void BuffSerial::print(const char pBuf){
|
||||
sendByte(pBuf);
|
||||
}
|
||||
|
||||
|
||||
void BuffSerial::println(const char *pBuf){
|
||||
print(pBuf);
|
||||
println();
|
||||
}
|
||||
|
||||
void BuffSerial::println(const char pBuf){
|
||||
print(pBuf);
|
||||
println();
|
||||
}
|
||||
|
||||
void BuffSerial::println(void){
|
||||
print("\r\n");
|
||||
}
|
||||
|
||||
void BuffSerial::printHex4(uint8_t data){
|
||||
uint8_t c = data & 0x0f;
|
||||
c += c < 10 ? '0' : 'A' - 10 ;
|
||||
sendByte(c);
|
||||
}
|
||||
|
||||
void BuffSerial::printHex8(uint8_t data){
|
||||
printHex4(data >> 4);
|
||||
printHex4(data);
|
||||
}
|
||||
|
||||
void BuffSerial::printDec(uint8_t data){
|
||||
uint8_t buf[3];
|
||||
uint8_t i = 0;
|
||||
if (data == 0){
|
||||
sendByte('0');
|
||||
return;
|
||||
}
|
||||
|
||||
while (data > 0){
|
||||
buf[i++] = data % 10;
|
||||
data /= 10;
|
||||
}
|
||||
for (; i > 0; i--)
|
||||
sendByte((buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
|
||||
}
|
||||
|
||||
// check rx buffer not empty
|
||||
bool BuffSerial::rxEnabled(void){
|
||||
return rxEnd;
|
||||
}
|
||||
|
||||
uint8_t BuffSerial::rxRead(void){
|
||||
#if defined(__AVR_ATmega8__)
|
||||
cbi(UCSRB, RXCIE); // disable RX complete interrupt
|
||||
#else
|
||||
cbi(UCSR0B, RXCIE0); // disable RX complete interrupt
|
||||
#endif
|
||||
uint8_t readkey = rxBuffer[rxBegin]; // read begin of received Buffer
|
||||
rxBegin++;
|
||||
if (rxBegin == rxEnd) rxBegin = rxEnd = 0; // if Buffer is empty reset Buffer
|
||||
#if defined(__AVR_ATmega8__)
|
||||
sbi(UCSRB, RXCIE); // enable RX complete interrupt
|
||||
#else
|
||||
sbi(UCSR0B, RXCIE0); // enable RX complete interrupt
|
||||
#endif
|
||||
|
||||
return readkey;
|
||||
}
|
||||
|
||||
BuffSerial bSerial;
|
49
arduino/libraries/BuffSerial/BuffSerial.h
Normal file
49
arduino/libraries/BuffSerial/BuffSerial.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
BuffSerial.h v.01 - serial with transmit buffer library for Wiring
|
||||
Created by Kochetkov Aleksey, 03.07.2009
|
||||
*/
|
||||
|
||||
#ifndef BuffSerial_h
|
||||
#define BuffSerial_h
|
||||
|
||||
#include "WProgram.h"
|
||||
|
||||
#define TX_BUFF_SIZE 240 // max 65535
|
||||
#define RX_BUFF_SIZE 25 // max 255
|
||||
#define TX_BUFF_MAX_LEN TX_BUFF_SIZE - 1
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
class BuffSerial{
|
||||
public:
|
||||
uint8_t rxBuffer[RX_BUFF_SIZE];
|
||||
uint8_t rxBegin;
|
||||
uint8_t rxEnd;
|
||||
uint8_t txBuffer[TX_BUFF_SIZE];
|
||||
uint16_t txBegin;
|
||||
uint16_t txEnd;
|
||||
uint8_t txFull;
|
||||
uint16_t txOverflow;
|
||||
void begin(long);
|
||||
void sendByte(uint8_t);
|
||||
void print(const char*);
|
||||
void print(const char);
|
||||
void println(const char*);
|
||||
void println(const char);
|
||||
void println(void);
|
||||
void printHex4(uint8_t);
|
||||
void printHex8(uint8_t);
|
||||
void printDec(uint8_t);
|
||||
bool rxEnabled(void);
|
||||
uint8_t rxRead(void);
|
||||
};
|
||||
|
||||
extern BuffSerial bSerial;
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user