mirror of
				https://github.com/halleysfifthinc/Toyota-AVC-LAN
				synced 2025-10-30 18:07:17 +00:00 
			
		
		
		
	Update to use attiny1616 AC2 and TCB1
- Change AVC output enable/disable to only change input/output of pin 7; only one pin should need to be used to send (i.e. actual differential signaling isn't being used, therefore, we can achieve the necessary (single-ended) differential voltage using only one pin, leaving the other outputting low) - Use virtual ports to enable setting output status with single instruction
This commit is contained in:
		
							parent
							
								
									0a9bd4d988
								
							
						
					
					
						commit
						feccda9e69
					
				
							
								
								
									
										13
									
								
								GlobalDef.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								GlobalDef.h
									
									
									
									
									
								
							| @ -18,14 +18,11 @@ | |||||||
| #define FALSE                   0 | #define FALSE                   0 | ||||||
| #define TRUE                    (!FALSE) | #define TRUE                    (!FALSE) | ||||||
| 
 | 
 | ||||||
| // AVC LAN bus directly connected to internal analog comparator (PD6/7)
 | // AVC LAN bus on AC2 (PA6/7)
 | ||||||
| // PD6 AIN0 +
 | // PA6 AINP0 +
 | ||||||
| // PD7 AIN1 -
 | // PA7 AINN1 -
 | ||||||
| #define DATAIN_PIN              ACSR | #define INPUT_IS_SET            ( bit_is_set( AC2_STATUS, AC_STATE_bp ) ) | ||||||
| #define DATAIN                  ACO | #define INPUT_IS_CLEAR          ( bit_is_clear( AC2_STATUS, AC_STATE_bp ) ) | ||||||
| 
 |  | ||||||
| #define INPUT_IS_SET            ( bit_is_set( DATAIN_PIN, DATAIN ) ) |  | ||||||
| #define INPUT_IS_CLEAR          ( bit_is_clear( DATAIN_PIN, DATAIN ) ) |  | ||||||
| 
 | 
 | ||||||
| #define LED_DDR                 DDRB | #define LED_DDR                 DDRB | ||||||
| #define LED_PORT                PORTB | #define LED_PORT                PORTB | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								avclandrv.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								avclandrv.c
									
									
									
									
									
								
							| @ -38,10 +38,12 @@ | |||||||
| 
 | 
 | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| #define AVC_OUT_EN()	sbi(PORTD, 6); sbi(DDRD, 6);  sbi(DDRD, 7); sbi(ACSR, ACD);	// Write mode
 | #define AVC_OUT_EN()	cbi(AC2_CTRLA, AC_ENABLE_bp); sbi(VPORTA_DIR, 6); // Write mode
 | ||||||
| #define AVC_OUT_DIS()	cbi(PORTD, 6); cbi(DDRD, 6);  cbi(DDRD, 7); cbi(ACSR, ACD); // Read mpde
 | #define AVC_OUT_DIS()	cbi(VPORTA_DIR, 6); sbi(AC2_CTRLA, AC_ENABLE_bp); // Read mode
 | ||||||
| #define AVC_SET_1()  	sbi(PORTD, 6); | #define AVC_SET_LOGICAL_1() \ | ||||||
| #define AVC_SET_0()  	cbi(PORTD, 6); |     __asm__ __volatile__ ("sbi VPORTA_OUT, 6;"); | ||||||
|  | #define AVC_SET_LOGICAL_0() \ | ||||||
|  |  	__asm__ __volatile__ ("cbi VPORTA_OUT, 6;"); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| byte CD_ID_1; | byte CD_ID_1; | ||||||
| @ -147,20 +149,20 @@ void AVC_HoldLine() | |||||||
|  // wait for free line
 |  // wait for free line
 | ||||||
|  byte line_busy = 1; |  byte line_busy = 1; | ||||||
| 
 | 
 | ||||||
|  TCNT0 = 0; |  TCB1.CNT = 0; | ||||||
|  do { |  do { | ||||||
|      while (INPUT_IS_CLEAR) { |      while (INPUT_IS_CLEAR) { | ||||||
|         /*	The comparison value was originally 25 with CK64 (tick period of 4.34 us)
 |         /*	The comparison value was originally 25 with CK64 (tick period of 4.34 us)
 | ||||||
|                  at a clock frequency 14.7456MHz. |                  at a clock frequency 14.7456MHz. | ||||||
|                 For a more accurate tick period of .5 us at 16MHz, the value should be approximately 225*/ |                 For a more accurate tick period of .5 us at 16MHz, the value should be approximately 225*/ | ||||||
|         if (TCNT0 >= 225) break; |         if (TCB1.CNT >= 900) break; | ||||||
|      } |      } | ||||||
|      if (TCNT0 > 216) line_busy=0; |      if (TCB1.CNT > 864) line_busy=0; | ||||||
|  } while (line_busy); |  } while (line_busy); | ||||||
| 
 | 
 | ||||||
|  // switch to out mode
 |  // switch to out mode
 | ||||||
|  AVC_OUT_EN(); |  AVC_OUT_EN(); | ||||||
|  AVC_SET_1(); |  AVC_SET_LOGICAL_1(); | ||||||
| 
 | 
 | ||||||
|  STARTEvent; |  STARTEvent; | ||||||
| } | } | ||||||
| @ -169,7 +171,7 @@ void AVC_HoldLine() | |||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| void AVC_ReleaseLine() | void AVC_ReleaseLine() | ||||||
| { | { | ||||||
|  AVC_SET_0(); |  AVC_SET_LOGICAL_0(); | ||||||
|  AVC_OUT_DIS(); |  AVC_OUT_DIS(); | ||||||
| } | } | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| @ -179,31 +181,21 @@ void AVC_ReleaseLine() | |||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| void AVCLan_Init() | void AVCLan_Init() | ||||||
| { | { | ||||||
|     // OUTPUT ( set as input for comparator )
 |     PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc; // Disable input buffer; recommended when using AC
 | ||||||
|     cbi(PORTD, 6); |     PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc; | ||||||
|     cbi(DDRD, 6); | 
 | ||||||
|  |     // Pull-ups are disabled by default
 | ||||||
|  |     VPORTA.DIR &= ~(PIN6_bm | PIN7_bm); // Zero pin 6 and 7 to set as input
 | ||||||
| 
 | 
 | ||||||
|     // INPUT
 |  | ||||||
|     cbi(PORTD, 7); |  | ||||||
|     cbi(DDRD, 7); |  | ||||||
| 
 | 
 | ||||||
|     // Analog comparator
 |     // Analog comparator
 | ||||||
|  |     AC2.CTRLA = AC_OUTEN_bm | AC_HYSMODE_25mV_gc | AC_ENABLE_bm; | ||||||
| 
 | 
 | ||||||
|     cbi(ADCSRB, ACME);	// Analog Comparator Multiplexer Enable - NO
 |     TCB1.CTRLB = TCB_ASYNC_bm | TCB_CNTMODE_SINGLE_gc; | ||||||
|     //cbi(ADCSRA, ADEN);
 |     TCB1.EVCTRL = TCB_CAPTEI_bm; | ||||||
|     /*
 |     TCB1.INTCTRL = TCB_CAPT_bm; | ||||||
|     cbi(ACSR, ACBG);	// Analog Comparator Bandgap Select
 |     EVSYS.ASYNCUSER0 = EVSYS_ASYNCUSER0_ASYNCCH0_gc; | ||||||
|                         // ACI: Analog Comparator Interrupt Flag
 |     TCB1.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm; | ||||||
| 
 |  | ||||||
|     cbi(ACSR, ACIE);	// Analog Comparator Interrupt Enable - NO
 |  | ||||||
|     cbi(ACSR, ACIC);	// Analog Comparator Input Capture Enable - NO
 |  | ||||||
|     */ |  | ||||||
|     cbi(ACSR, ACIS1);	// Analog Comparator Interrupt Mode Select
 |  | ||||||
|     cbi(ACSR, ACIS0);  // Comparator Interrupt on Output Toggle
 |  | ||||||
| 
 |  | ||||||
|     cbi(ACSR, ACD); 	// Analog Comparator Disable - NO
 |  | ||||||
| 
 |  | ||||||
|     TCCR0B = _BV(CS01);	// Timer 0 prescaler = 8 ( 2 count / us )
 |  | ||||||
| 
 | 
 | ||||||
|     message_len   = 0; |     message_len   = 0; | ||||||
|     answerReq     = cmNull; |     answerReq     = cmNull; | ||||||
| @ -228,9 +220,9 @@ byte AVCLan_Read_Byte(byte length) | |||||||
| 
 | 
 | ||||||
|  while (1) { |  while (1) { | ||||||
|    while (INPUT_IS_CLEAR); |    while (INPUT_IS_CLEAR); | ||||||
|    TCNT0 = 0; |    TCB1.CNT = 0; | ||||||
|    while (INPUT_IS_SET); 	// If input was set for less than a
 |    while (INPUT_IS_SET); 	// If input was set for less than 26 us
 | ||||||
|    if ( TCNT0 < 52 ) {		// generous half period, bit was a 1
 |    if ( TCB1.CNT < 208 ) {  // (a generous half period), bit was a 1
 | ||||||
|       bite++; |       bite++; | ||||||
|       parity_bit++; |       parity_bit++; | ||||||
|    } |    } | ||||||
| @ -240,19 +232,24 @@ byte AVCLan_Read_Byte(byte length) | |||||||
|  } |  } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void set_AVC_logic_for(uint8_t val, uint16_t period) { | ||||||
|  |     if (val == 1) { | ||||||
|  |         AVC_SET_LOGICAL_1(); | ||||||
|  |     } else { | ||||||
|  |         AVC_SET_LOGICAL_0(); | ||||||
|  |     } | ||||||
|  |     TCB1.CCMP = period; | ||||||
|  |     EVSYS.ASYNCSTROBE = EVSYS_ASYNCCH00_bm; | ||||||
|  |     loop_until_bit_is_set(TCB1_INTFLAGS, 0); | ||||||
|  |     TCB1_INTFLAGS = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // DONE: Timing adjusted
 | // DONE: Timing adjusted
 | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| byte AVCLan_Send_StartBit() | byte AVCLan_Send_StartBit() | ||||||
| { | { | ||||||
|     AVC_SET_1(); |     set_AVC_logic_for(1, 1328); // 166 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     TCNT0 = 0; |     set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     while( TCNT0 < 255 ); |  | ||||||
|     TCNT0 = 0; |  | ||||||
|     while( TCNT0 < 77 ); |  | ||||||
| 
 |  | ||||||
|     AVC_SET_0(); |  | ||||||
|     TCNT0 = 0; |  | ||||||
|     while( TCNT0 < 38 ); |  | ||||||
| 
 | 
 | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| @ -261,69 +258,47 @@ byte AVCLan_Send_StartBit() | |||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| void AVCLan_Send_Bit1() | void AVCLan_Send_Bit1() | ||||||
| { | { | ||||||
|     AVC_SET_1(); |     set_AVC_logic_for(1, 164); // 20.5 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     TCNT0 = 0; |     set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     while( TCNT0 < 41 ); |  | ||||||
| 
 |  | ||||||
|     AVC_SET_0(); |  | ||||||
|     TCNT0 = 0; |  | ||||||
|     while( TCNT0 < 38 );							// 12-21 us
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DONE: Timing adjusted
 |  | ||||||
| //------------------------------------------------------------------------------
 |  | ||||||
| void AVCLan_Send_Bit0() | void AVCLan_Send_Bit0() | ||||||
| { | { | ||||||
|     AVC_SET_1(); |     set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     TCNT0 = 0; |     set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     while( TCNT0 < 68 );						// 28-37 us
 |  | ||||||
| 
 |  | ||||||
|     AVC_SET_0(); |  | ||||||
|     TCNT0 = 0; |  | ||||||
|     while( TCNT0 < 11 );								// 00-09 us
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //	DONE: Timing adjusted.
 | //	DONE: Timing adjusted.
 | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| byte AVCLan_Read_ACK() | byte AVCLan_Read_ACK() | ||||||
| { | { | ||||||
|     AVC_SET_1(); |     set_AVC_logic_for(1, 152); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     TCNT0 = 0; |     AVC_SET_LOGICAL_0(); // Replace with AVC_ReleaseLine?
 | ||||||
|     while( TCNT0 < 38 ); |  | ||||||
| 
 |  | ||||||
|     AVC_SET_0();												// Replace with AVC_ReleaseLine?
 |  | ||||||
|     AVC_OUT_DIS(); // switch to read mode
 |     AVC_OUT_DIS(); // switch to read mode
 | ||||||
| 
 | 
 | ||||||
|  |     TCB1.CNT = 0; | ||||||
|     while(1) { |     while(1) { | ||||||
|     if (INPUT_IS_SET && (TCNT0 > 52 )) break;		// Make sure INPUT is not still set from us
 |     if (INPUT_IS_SET && (TCB1.CNT > 208 )) break; // Make sure INPUT is not still set from us
 | ||||||
|     // Line of experimentation: Try changing TCNT0 comparison value or remove check entirely
 |     // Line of experimentation: Try changing TCNT0 comparison value or remove check entirely
 | ||||||
|     if (TCNT0 > 75 ) return 1;					// Not sure if this fix is intent correct
 |     if (TCB1.CNT > 300 ) return 1; // Not sure if this fix is intent correct
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while(INPUT_IS_SET); |     while(INPUT_IS_SET); | ||||||
|     AVC_OUT_EN();	// back to write mode
 |     AVC_OUT_EN();	// back to write mode
 | ||||||
|     return 0; |     return 0; | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //	DONE: Timing adjusted.
 |  | ||||||
| //------------------------------------------------------------------------------
 |  | ||||||
| byte AVCLan_Send_ACK() | byte AVCLan_Send_ACK() | ||||||
| { | { | ||||||
|     TCNT0 = 0; |     TCB1.CNT = 0; | ||||||
|     while (INPUT_IS_CLEAR)	{ |     while (INPUT_IS_CLEAR)	{ | ||||||
|         if (TCNT0 >= 225) return 0;			// max wait time
 |         if (TCB1.CNT >= 900) return 0; // max wait time
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     AVC_OUT_EN(); |     AVC_OUT_EN(); | ||||||
| 
 | 
 | ||||||
|     AVC_SET_1(); |     set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     TCNT0 = 0; |     set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
 | ||||||
|     while( TCNT0 < 68 );								//28-37
 |  | ||||||
| 
 |  | ||||||
|     AVC_SET_0(); |  | ||||||
|     TCNT0 = 0; |  | ||||||
|     while( TCNT0 < 11 );									//00-09
 |  | ||||||
| 
 | 
 | ||||||
|     AVC_OUT_DIS(); |     AVC_OUT_DIS(); | ||||||
| 
 | 
 | ||||||
| @ -533,12 +508,12 @@ byte AVCLan_SendData() | |||||||
|     // wait for free line
 |     // wait for free line
 | ||||||
|     byte line_busy = 1; |     byte line_busy = 1; | ||||||
| 
 | 
 | ||||||
|     TCNT0 = 0; |     TCB1.CNT = 0; | ||||||
|     do { |     do { | ||||||
|         while (INPUT_IS_CLEAR) { |         while (INPUT_IS_CLEAR) { | ||||||
|         if ( TCNT0 >= 225 ) break; |         if ( TCB1.CNT >= 900 ) break; | ||||||
|         } |         } | ||||||
|         if ( TCNT0 > 216 ) line_busy=0; |         if ( TCB1.CNT > 864 ) line_busy=0; | ||||||
|     } while (line_busy); |     } while (line_busy); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -617,12 +592,12 @@ byte AVCLan_SendDataBroadcast() | |||||||
|     // wait for free line
 |     // wait for free line
 | ||||||
|     byte line_busy = 1; |     byte line_busy = 1; | ||||||
| 
 | 
 | ||||||
|     TCNT0 = 0; |     TCB1.CNT = 0; | ||||||
|     do { |     do { | ||||||
|         while (INPUT_IS_CLEAR) { |         while (INPUT_IS_CLEAR) { | ||||||
|         if ( TCNT0 >= 225 ) break; |         if ( TCB1.CNT >= 900 ) break; | ||||||
|         } |         } | ||||||
|         if ( TCNT0 > 216 ) line_busy=0; |         if ( TCB1.CNT > 864 ) line_busy=0; | ||||||
|     } while (line_busy); |     } while (line_busy); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -1025,10 +1000,10 @@ void ShowOutMessage() | |||||||
|         sbi(TCCR1B, CS10); |         sbi(TCCR1B, CS10); | ||||||
|         word n = 60000; |         word n = 60000; | ||||||
|         TCNT1 = 0; |         TCNT1 = 0; | ||||||
|         AVC_SET_1(); |         AVC_SET_LOGICAL_1(); | ||||||
|         while ( TCNT1 < n ); |         while ( TCNT1 < n ); | ||||||
|         TCNT1 = 0; |         TCNT1 = 0; | ||||||
|         AVC_SET_0(); |         AVC_SET_LOGICAL_0(); | ||||||
|         while ( TCNT1 < n ); |         while ( TCNT1 < n ); | ||||||
|         cbi(TCCR1B, CS10); |         cbi(TCCR1B, CS10); | ||||||
|         AVC_OUT_DIS(); |         AVC_OUT_DIS(); | ||||||
|  | |||||||
| @ -119,8 +119,8 @@ int main() | |||||||
| 				break; | 				break; | ||||||
| 			case 'R':	RS232_Print_P(PSTR("REGIST:\n")); | 			case 'R':	RS232_Print_P(PSTR("REGIST:\n")); | ||||||
|   			AVCLan_Command( cmRegister ); |   			AVCLan_Command( cmRegister ); | ||||||
|       	TCNT0 = 0; |                 TCB1.CNT = 0; | ||||||
|       	while( TCNT0 < 135 ); |                 while( TCB1.CNT < 540 ); | ||||||
|   				CHECK_AVC_LINE; |   				CHECK_AVC_LINE; | ||||||
|   			break; |   			break; | ||||||
| 			case 'r':	AVCLan_Register(); | 			case 'r':	AVCLan_Register(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user