From b87cc0fcafc52c34e130c4542ff50612e67d8956 Mon Sep 17 00:00:00 2001 From: OlegStepanenko_noute Date: Wed, 30 Mar 2016 20:26:05 +0300 Subject: [PATCH] back timer2, add main sketch --- AVCLan_mini/AVCLanDrv.cpp | 103 +++++++++++++-------------------- AVCLan_mini/AVCLan_mini.ino | 31 +++++----- AVCLan_mini/config.h | 41 +++++++------ sketch/sketchbook_20100805.rar | Bin 0 -> 16153 bytes 4 files changed, 80 insertions(+), 95 deletions(-) create mode 100644 sketch/sketchbook_20100805.rar diff --git a/AVCLan_mini/AVCLanDrv.cpp b/AVCLan_mini/AVCLanDrv.cpp index 112a06a..d1fc9d9 100644 --- a/AVCLan_mini/AVCLanDrv.cpp +++ b/AVCLan_mini/AVCLanDrv.cpp @@ -7,45 +7,25 @@ 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 -#ifdef AVCLAN_ST485 - sbi(DATAOUT_DDR, DATAOUT); - sbi(OUTEN_DDR, OUTEN); - AVC_OUT_DIS; - OUTPUT_SET_0; -#else - //avclan driver on PCA82C250 & LM239N + //avclan driver on PCA82C250 sbi(DATAOUT_DDR, DATAOUT); AVC_OUT_DIS; OUTPUT_SET_0; -#endif -#endif + // timer2 setup, prescaler factor - 8 #if defined(__AVR_ATmega8__) // ASSR=0x00; TCCR2 = 0x02; - // TCNT0=0x00; + // TCNT2=0x00; // OCR2=0x00; #else // ATMega168 // ASSR=0x00; // TCCR2A=0x00; - TCCR0B = 0x02; - // TCNT0=0x00; + TCCR2B = 0x02; + // TCNT2=0x00; // OCR2A=0x00; // OCR2B=0x00; #endif @@ -75,22 +55,19 @@ word AVCLanDrv::readBits (byte nbBits) } // Reset timer to measure bit length. - TCNT0 = 0; + 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 (TCNT0 < AVC_BIT_0_HOLD_ON_MIN_LENGTH) { + if (TCNT2 < AVC_BIT_0_HOLD_ON_MIN_LENGTH) { // Set new bit. data |= 0x0001; // Adjust parity. _parityBit = !_parityBit; } } - while (INPUT_IS_CLEAR && TCNT0 < AVC_NORMAL_BIT_LENGTH); + while (INPUT_IS_CLEAR && TCNT2 < AVC_NORMAL_BIT_LENGTH); - // char buff[10] = {0}; - // sprintf(buff, "%x", data ); - // // bSDLog.logs( buff ); return data; } @@ -106,18 +83,18 @@ byte AVCLanDrv::_readMessage () // Start bit. while (INPUT_IS_CLEAR); - TCCR0B = 0x03; // prescaler 32 - TCNT0 = 0; + TCCR2B = 0x03; // prescaler 32 + TCNT2 = 0; // Wait until falling edge. while (INPUT_IS_SET) { - t = TCNT0; + t = TCNT2; if (t > 0xFF) { - TCCR0B = 0x02; // prescaler 8 + TCCR2B = 0x02; // prescaler 8 SREG = oldSREG; return 1; } } - TCCR0B = 0x02; // prescaler 8 + TCCR2B = 0x02; // prescaler 8 if (t < AVC_START_BIT_HOLD_ON_MIN_LENGTH) { //if (t < 0x16){ @@ -231,17 +208,17 @@ byte AVCLanDrv::readMessage () ////-------------------------------------------------------------------------------- //{ // // Reset timer to measure bit length. -// TCCR0B = 0x03; // prescaler 32 -// TCNT0 = 0; +// TCCR2B = 0x03; // prescaler 32 +// TCNT2 = 0; // OUTPUT_SET_1; // // // Pulse level high duration. -// while ( TCNT0 < AVC_START_BIT_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_START_BIT_HOLD_ON_LENGTH ); // OUTPUT_SET_0; // // // Pulse level low duration until ~185 us. -// while ( TCNT0 < AVC_START_BIT_LENGTH ); -// TCCR0B = 0x02; // prescaler 8 +// while ( TCNT2 < AVC_START_BIT_LENGTH ); +// TCCR2B = 0x02; // prescaler 8 // //} @@ -251,17 +228,17 @@ void AVCLanDrv::send1BitWord (bool data) //-------------------------------------------------------------------------------- { // Reset timer to measure bit length. - TCNT0 = 0; + TCNT2 = 0; OUTPUT_SET_1; if (data) { - while (TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH); + while (TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH); } else { - while (TCNT0 < AVC_BIT_0_HOLD_ON_LENGTH); + while (TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH); } OUTPUT_SET_0; - while (TCNT0 < AVC_NORMAL_BIT_LENGTH); + while (TCNT2 < AVC_NORMAL_BIT_LENGTH); } //// Send a 4 bit word to the AVCLan @@ -274,20 +251,20 @@ void AVCLanDrv::send1BitWord (bool data) // // Most significant bit out first. // for ( char nbBits = 0; nbBits < 4; nbBits++ ) { // // Reset timer to measure bit length. -// TCNT0 = 2; +// TCNT2 = 2; // OUTPUT_SET_1; // // if (data & 0x8) { // // Adjust parity. // _parityBit = ! _parityBit; -// while ( TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH ); // } else { -// while ( TCNT0 < AVC_BIT_0_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH ); // } // // OUTPUT_SET_0; // // Hold output low until end of bit. -// while ( TCNT0 < AVC_NORMAL_BIT_LENGTH ); +// while ( TCNT2 < AVC_NORMAL_BIT_LENGTH ); // // // Fetch next bit. // data <<= 1; @@ -304,20 +281,20 @@ void AVCLanDrv::send1BitWord (bool data) // // Most significant bit out first. // for ( char nbBits = 0; nbBits < 8; nbBits++ ) { // // Reset timer to measure bit length. -// TCNT0 = 2; +// TCNT2 = 2; // OUTPUT_SET_1; // // if (data & 0x80) { // // Adjust parity. // _parityBit = ! _parityBit; -// while ( TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH ); // } else { -// while ( TCNT0 < AVC_BIT_0_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH ); // } // // OUTPUT_SET_0; // // Hold output low until end of bit. -// while ( TCNT0 < AVC_NORMAL_BIT_LENGTH ); +// while ( TCNT2 < AVC_NORMAL_BIT_LENGTH ); // // // Fetch next bit. // data <<= 1; @@ -334,20 +311,20 @@ void AVCLanDrv::send1BitWord (bool data) // // Most significant bit out first. // for ( char nbBits = 0; nbBits < 12; nbBits++ ) { // // Reset timer to measure bit length. -// TCNT0 = 2; +// TCNT2 = 2; // OUTPUT_SET_1; // // if (data & 0x0800) { // // Adjust parity. // _parityBit = ! _parityBit; -// while ( TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH ); // } else { -// while ( TCNT0 < AVC_BIT_0_HOLD_ON_LENGTH ); +// while ( TCNT2 < AVC_BIT_0_HOLD_ON_LENGTH ); // } // // OUTPUT_SET_0; // // Hold output low until end of bit. -// while ( TCNT0 < AVC_NORMAL_BIT_LENGTH ); +// while ( TCNT2 < AVC_NORMAL_BIT_LENGTH ); // // // Fetch next bit. // data <<= 1; @@ -361,11 +338,11 @@ bool AVCLanDrv::isAvcBusFree (void) //-------------------------------------------------------------------------------- { // Reset timer. - TCNT0 = 0; + TCNT2 = 0; while (INPUT_IS_CLEAR) { // We assume the bus is free if anything happens for the length of 1 bit. - if (TCNT0 > AVC_NORMAL_BIT_LENGTH) { + if (TCNT2 > AVC_NORMAL_BIT_LENGTH) { return true; } } @@ -384,21 +361,21 @@ bool AVCLanDrv::isAvcBusFree (void) // // taken over the bus maintaining the pulse until the equivalent of a bit '0' (32 us) is formed. // // // Reset timer to measure bit length. -// TCNT0 = 0; +// TCNT2 = 0; // OUTPUT_SET_1; // // // Generate bit '0'. -// while (TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH); +// while (TCNT2 < AVC_BIT_1_HOLD_ON_LENGTH); // OUTPUT_SET_0; // // AVC_OUT_DIS; // -// while (TCNT0 < AVC_BIT_1_HOLD_ON_LENGTH + AVC_1U_LENGTH); +// 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 (TCNT0 > AVC_BIT_0_HOLD_ON_MIN_LENGTH) { +// 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; diff --git a/AVCLan_mini/AVCLan_mini.ino b/AVCLan_mini/AVCLan_mini.ino index 235a417..9527619 100644 --- a/AVCLan_mini/AVCLan_mini.ino +++ b/AVCLan_mini/AVCLan_mini.ino @@ -7,21 +7,19 @@ //-------------------------------------------------------------------------------- #define LED_ON sbi(LED_PORT, LED_OUT); -#define LED_OFF cbi(LED_PORT, LED_OUT); +#define LED_OFF cbi(LED_PORT, LED_OUT); -#define HONDA_DIS_ON sbi(LED_PORT, COMMUT_OUT); -#define HONDA_DIS_OFF cbi(LED_PORT, COMMUT_OUT); +#define HONDA_DIS_ON sbi(COMMUT_PORT, COMMUT_OUT); +#define HONDA_DIS_OFF cbi(COMMUT_PORT, COMMUT_OUT); static int MAX_ERROR_COUNT = 30; byte errorID; int error_count; +char BUFFF[15]; //-------------------------------------------------------------------------------- void setup() //-------------------------------------------------------------------------------- { - sbi(LED_DDR, COMMUT_OUT); - cbi(LED_PORT, COMMUT_OUT); - avclan.begin(); avclanHonda.begin(); errorID = 0; @@ -29,6 +27,7 @@ void setup() avclanBT.begin(); avclanBT.println("Start HONDA avclan."); + LED_ON; } //-------------------------------------------------------------------------------- @@ -56,6 +55,10 @@ void loop() avclanHonda.getActionID(); if ( avclan.actionID != ACT_NONE ) { + sprintf( BUFFF, "Action: %d", avclan.actionID ); + avclanBT.println( BUFFF ); + + LED_ON; avclanHonda.processAction( (AvcActionID)avclan.actionID ); } } else { @@ -63,11 +66,6 @@ void loop() else error_count = 1; errorID = res; - - if ( error_count > MAX_ERROR_COUNT ) { - error_count = 0; - avclanHonda.setHondaDis(true); - } } } @@ -82,11 +80,14 @@ void loop() } } - if ( !error_count && errorID ) { - char BUFFF[15]; - sprintf(BUFFF, "Error: %d", errorID); + if ( error_count > MAX_ERROR_COUNT ) { + error_count = 0; + avclanHonda.setHondaDis(true); + + LED_OFF; + + sprintf(BUFFF, "Error: %d", errorID ); avclanBT.println( BUFFF ); - delay(2000); } } diff --git a/AVCLan_mini/config.h b/AVCLan_mini/config.h index c97d6a1..0993282 100644 --- a/AVCLan_mini/config.h +++ b/AVCLan_mini/config.h @@ -11,31 +11,38 @@ #define MAXSENDATTEMP 3 //********** arduino & driver based on PCA82C250 ********** +// http://pighixxx.com/nanopdf.pdf #ifdef AVCLAN_PCA82C250 #define AVCLANDRIVER_TYPE "Arduino - PCA82C250" -// define out pin (pin D6 arduino) -#define DATAOUT_DDR DDRD -#define DATAOUT_PORT PORTD -#define DATAOUT_PIN PIND -#define DATAOUT 6 +// define out pin (pin 8 arduino) for AVCLAN_PCA82C250 +#define DATAOUT_DDR DDRB +#define DATAOUT_PORT PORTB +#define DATAOUT_PIN PINB +#define DATAOUT 0 -// define in pin (pin D5 arduino) -#define DATAIN_DDR DDRD -#define DATAIN_PORT PORTD -#define DATAIN_PIN PIND -#define DATAIN 5 +// define in pin (pin 9 arduino) for AVCLAN_PCA82C250 +#define DATAIN_DDR DDRB +#define DATAIN_PORT PORTB +#define DATAIN_PIN PINB +#define DATAIN 1 + +// connected to digital pin A0 +#define COMMUT_DDR DDRC +#define COMMUT_PORT PORTC +#define COMMUT_PIN PINC +#define COMMUT_OUT 0 // LED connected to digital pin 13 -#define LED_DDR DDRC -#define LED_PORT PORTC -#define LED_PIN PINC -#define COMMUT_OUT 0 +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED_OUT 5 // AZFM board activate -#define AZFM_INIT -#define AZFM_ON -#define AZFM_OFF +//#define AZFM_INIT +//#define AZFM_ON +//#define AZFM_OFF #endif diff --git a/sketch/sketchbook_20100805.rar b/sketch/sketchbook_20100805.rar new file mode 100644 index 0000000000000000000000000000000000000000..629613598cfea8d22c11b37d770f48ce615eff70 GIT binary patch literal 16153 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