mirror of
https://github.com/halleysfifthinc/Toyota-AVC-LAN
synced 2025-06-06 15:36:47 +00:00
Setup timing better (fuses, clock speed, TCB clock speed)
This commit is contained in:
parent
09bcd75811
commit
7245695bc7
@ -1,11 +1,50 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(WITH_MCU OFF)
|
||||
set(AVR_MCU "attiny3216")
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/avr-gcc-toolchain.cmake")
|
||||
|
||||
project(avr-avc-lan VERSION 1 LANGUAGES C CXX ASM)
|
||||
project(avclan-mockingboard VERSION 1 LANGUAGES C CXX ASM)
|
||||
|
||||
set(FREQSEL 16MHz CACHE STRING "Select the operating frequency")
|
||||
set_property(CACHE FREQSEL PROPERTY STRINGS "20MHz" "16MHz")
|
||||
|
||||
if(FREQSEL MATCHES "20MHz")
|
||||
set(F_CPU 20000000L)
|
||||
set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -U osccfg:w:0x2:m)
|
||||
else()
|
||||
set(F_CPU 16000000L)
|
||||
set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -U osccfg:w:0x1:m)
|
||||
endif()
|
||||
|
||||
option(CLK_PRESCALE "Enable the main clock prescaler")
|
||||
cmake_dependent_option(CLK_PRESCALE_DIV "Prescaler divisor" CLKCTRL_PDIV_2X_gc STRING "CLK_PRESCALE")
|
||||
if(DEFINED CACHE{CLK_PRESCALE_DIV})
|
||||
set_property(CACHE CLK_PRESCALE_DIV PROPERTY STRINGS
|
||||
CLKCTRL_PDIV_2X_gc
|
||||
CLKCTRL_PDIV_4X_gc
|
||||
CLKCTRL_PDIV_8X_gc
|
||||
CLKCTRL_PDIV_16X_gc
|
||||
CLKCTRL_PDIV_32X_gc
|
||||
CLKCTRL_PDIV_64X_gc
|
||||
CLKCTRL_PDIV_6X_gc
|
||||
CLKCTRL_PDIV_10X_gc
|
||||
CLKCTRL_PDIV_12X_gc
|
||||
CLKCTRL_PDIV_24X_gc
|
||||
CLKCTRL_PDIV_48X_gc
|
||||
)
|
||||
else()
|
||||
set(CLK_PRESCALE_DIV CLKCTRL_PDIV_2X_gc)
|
||||
endif()
|
||||
|
||||
set(TCB_CLKSEL "TCB_CLKSEL_CLKDIV2_gc" CACHE STRING "Choose the clock for TCB")
|
||||
set_property(CACHE TCB_CLKSEL PROPERTY STRINGS
|
||||
TCB_CLKSEL_CLKDIV1_gc
|
||||
TCB_CLKSEL_CLKDIV2_gc
|
||||
TCB_CLKSEL_CLKTCA_gc
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.3")
|
||||
@ -61,18 +100,24 @@ if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
add_avr_executable(sniffer
|
||||
# Set startup time to 8 ms (0x4)
|
||||
set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -U syscfg1:w:0x4:m)
|
||||
|
||||
add_avr_executable(mockingboard
|
||||
src/sniffer.c
|
||||
src/com232.c
|
||||
src/avclandrv.c)
|
||||
|
||||
target_link_options(sniffer PUBLIC
|
||||
target_link_options(mockingboard PUBLIC
|
||||
-B "${attiny_atpack_SOURCE_DIR}/gcc/dev/${AVR_MCU}"
|
||||
)
|
||||
target_compile_definitions(sniffer PRIVATE
|
||||
F_CPU=16000000L
|
||||
target_compile_definitions(mockingboard PRIVATE
|
||||
F_CPU=${F_CPU}
|
||||
CLK_PRESCALE=$<IF:$<BOOL:${CLK_PRESCALE}>,0x01,0x00>
|
||||
CLK_PRESCALE_DIV=${CLK_PRESCALE_DIV}
|
||||
TCB_CLKSEL=${TCB_CLKSEL}
|
||||
)
|
||||
target_compile_options(sniffer PRIVATE
|
||||
target_compile_options(mockingboard PRIVATE
|
||||
--param=min-pagesize=0
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
|
@ -92,6 +92,7 @@
|
||||
|
||||
#include "avclandrv.h"
|
||||
#include "com232.h"
|
||||
#include "timing.h"
|
||||
|
||||
// Enable AVC bus Tx
|
||||
#define AVC_OUT_EN() \
|
||||
@ -265,12 +266,12 @@ void AVCLAN_init() {
|
||||
TCB0.CTRLB = TCB_CNTMODE_PW_gc;
|
||||
TCB0.INTCTRL = TCB_CAPT_bm;
|
||||
TCB0.EVCTRL = TCB_CAPTEI_bm;
|
||||
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm;
|
||||
TCB0.CTRLA = TCB_CLKSEL | TCB_ENABLE_bm;
|
||||
|
||||
// TCB1 for send bit timing
|
||||
TCB1.CTRLB = TCB_CNTMODE_INT_gc;
|
||||
TCB1.CCMP = 0xFFFF;
|
||||
TCB1.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm;
|
||||
TCB1.CTRLA = TCB_CLKSEL | TCB_ENABLE_bm;
|
||||
|
||||
answerReq = cm_Null;
|
||||
|
||||
@ -293,34 +294,36 @@ void set_AVC_logic_for(uint8_t val, uint16_t period) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t AVCLAN_sendbit_start() {
|
||||
set_AVC_logic_for(1, 1328); // 166 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
|
||||
return 1;
|
||||
void AVCLAN_sendbit_start() {
|
||||
set_AVC_logic_for(0, AVCLAN_STARTBIT_LOGIC_0); // 166 us
|
||||
set_AVC_logic_for(1, AVCLAN_STARTBIT_LOGIC_1); // 19 us
|
||||
}
|
||||
|
||||
void AVCLAN_sendbit_1() {
|
||||
set_AVC_logic_for(1, 164); // 20.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 152); // 19 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, AVCLAN_BIT1_LOGIC_0); // 20.5 us
|
||||
set_AVC_logic_for(1, AVCLAN_BIT1_LOGIC_1); // 19 us
|
||||
}
|
||||
|
||||
void AVCLAN_sendbit_0() {
|
||||
set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, AVCLAN_BIT0_LOGIC_0); // 34 us
|
||||
set_AVC_logic_for(1, AVCLAN_BIT0_LOGIC_1); // 5.5 us
|
||||
}
|
||||
|
||||
void AVCLAN_sendbit_ACK() {
|
||||
TCB1.CNT = 0;
|
||||
|
||||
// Wait for controller to begin ACK bit
|
||||
while (INPUT_IS_CLEAR) {
|
||||
if (TCB1.CNT >= 900)
|
||||
return; // max wait time
|
||||
// Wait for approx the length of a bit; any longer and something has clearly
|
||||
// gone wrong
|
||||
if (TCB1.CNT >= AVCLAN_BIT_LENGTH)
|
||||
return;
|
||||
}
|
||||
|
||||
AVC_OUT_EN();
|
||||
|
||||
set_AVC_logic_for(1, 272); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, 44); // 5.5 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
set_AVC_logic_for(0, AVCLAN_BIT0_LOGIC_0); // 34 us
|
||||
set_AVC_logic_for(1, AVCLAN_BIT0_LOGIC_1); // 5.5 us
|
||||
|
||||
AVC_OUT_DIS();
|
||||
}
|
||||
@ -395,7 +398,7 @@ uint8_t AVCLAN_sendbyte(const uint8_t *byte) {
|
||||
|
||||
ISR(TCB0_INT_vect) {
|
||||
// If input was set for less than 26 us (a generous half period), bit was a 1
|
||||
if (TCB0.CCMP < 208) {
|
||||
if (TCB0.CCMP < (uint16_t)AVCLAN_READBIT_THRESHOLD) {
|
||||
READING_BYTE++;
|
||||
READING_PARITY++;
|
||||
}
|
||||
@ -418,7 +421,15 @@ uint8_t AVCLAN_readbitsi(uint8_t *bits, uint8_t len) {
|
||||
READING_NBITS = len;
|
||||
sei();
|
||||
|
||||
while (READING_NBITS != 0) {};
|
||||
TCB1.CNT = 0;
|
||||
while (READING_NBITS != 0) {
|
||||
// Duration of `len` bits + 10%
|
||||
if (TCB1.CNT > (((uint16_t)AVCLAN_BIT_LENGTH * 11 * len) / 10)) {
|
||||
READING_BYTE = 0;
|
||||
READING_PARITY = 0;
|
||||
break; // Should have finished by now; something's wrong
|
||||
}
|
||||
};
|
||||
|
||||
cli();
|
||||
*bits = READING_BYTE;
|
||||
@ -448,7 +459,15 @@ uint8_t AVCLAN_readbyte(uint8_t *byte) {
|
||||
READING_NBITS = 8;
|
||||
sei();
|
||||
|
||||
while (READING_NBITS != 0) {};
|
||||
TCB1.CNT = 0;
|
||||
while (READING_NBITS != 0) {
|
||||
// Duration of byte + 10%
|
||||
if (TCB1.CNT > (((uint16_t)AVCLAN_BIT_LENGTH * 11 * 8) / 10)) {
|
||||
READING_BYTE = 0;
|
||||
READING_PARITY = 0;
|
||||
break; // Should have finished by now; something's wrong
|
||||
}
|
||||
};
|
||||
|
||||
cli();
|
||||
*byte = READING_BYTE;
|
||||
@ -459,20 +478,19 @@ uint8_t AVCLAN_readbyte(uint8_t *byte) {
|
||||
}
|
||||
|
||||
uint8_t AVCLAN_readbit_ACK() {
|
||||
set_AVC_logic_for(1, 152); // 34 us @ 125 ns tick (for F_CPU = 16MHz)
|
||||
AVC_SET_LOGICAL_0(); // Replace with AVC_ReleaseLine?
|
||||
AVC_OUT_DIS(); // switch to read mode
|
||||
|
||||
TCB1.CNT = 0;
|
||||
set_AVC_logic_for(0, AVCLAN_BIT1_LOGIC_0); // 20.5 us
|
||||
AVC_SET_LOGICAL_1();
|
||||
AVC_OUT_DIS();
|
||||
|
||||
while (1) {
|
||||
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
|
||||
if (TCB1.CNT > 300)
|
||||
return 1; // Not sure if this fix is intent correct
|
||||
if (INPUT_IS_SET && (TCB1.CNT > AVCLAN_READBIT_THRESHOLD))
|
||||
break; // ACK
|
||||
if (TCB1.CNT > AVCLAN_BIT_LENGTH)
|
||||
return 1; // NAK
|
||||
}
|
||||
|
||||
// Check/wait in case we get here before peripheral finishes ACK bit
|
||||
while (INPUT_IS_SET) {}
|
||||
AVC_OUT_EN(); // back to write mode
|
||||
return 0;
|
||||
@ -669,7 +687,8 @@ uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame) {
|
||||
TCB1.CNT = 0;
|
||||
do {
|
||||
while (INPUT_IS_CLEAR) {
|
||||
if (TCB1.CNT >= 900)
|
||||
// Wait for 120% of a bit length
|
||||
if (TCB1.CNT >= (uint16_t)(AVCLAN_BIT_LENGTH * 12 / 10))
|
||||
break;
|
||||
}
|
||||
if (TCB1.CNT > 864)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/sfr_defs.h>
|
||||
#include <avr/xmega.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "avclandrv.h"
|
||||
@ -217,6 +218,8 @@ void Setup() {
|
||||
printAllFrames = 1;
|
||||
echoCharacters = 1;
|
||||
|
||||
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, (CLK_PRESCALE | CLK_PRESCALE_DIV));
|
||||
|
||||
general_GPIO_init();
|
||||
|
||||
// Setup RTC as 1 sec periodic timer
|
||||
|
51
src/timing.h
Normal file
51
src/timing.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef _TIMING_HPP_
|
||||
#define _TIMING_HPP_
|
||||
|
||||
#if CLK_PRESCALE == 0x01
|
||||
#error "Not implemented"
|
||||
#else
|
||||
|
||||
#if F_CPU == 20000000L
|
||||
#define CPU_CYCLE 50
|
||||
#elif F_CPU == 16000000L
|
||||
#define CPU_CYCLE 62.5
|
||||
#else
|
||||
#error "Not implemented"
|
||||
#endif
|
||||
|
||||
#ifndef TCB_CLKSEL_CLKDIV1_gc
|
||||
#define TCB_CLKSEL_CLKDIV1_gc (0x00 << 1)
|
||||
#endif
|
||||
|
||||
#ifndef TCB_CLKSEL_CLKDIV2_gc
|
||||
#define TCB_CLKSEL_CLKDIV2_gc (0x01 << 1)
|
||||
#endif
|
||||
|
||||
#ifndef TCB_CLKSEL_CLKTCA_gc
|
||||
#define TCB_CLKSEL_CLKTCA_gc (0x02 << 1)
|
||||
#endif
|
||||
|
||||
#if TCB_CLKSEL == TCB_CLKSEL_CLKDIV1_gc
|
||||
#define TCB_TICK (CPU_CYCLE)
|
||||
#elif TCB_CLKSEL == TCB_CLKSEL_CLKDIV2_gc
|
||||
#define TCB_TICK (CPU_CYCLE * 2)
|
||||
#elif TCB_CLKSEL == TCB_CLKSEL_CLKTCA_gc
|
||||
#error "Not implemented"
|
||||
#endif
|
||||
|
||||
#define AVCLAN_STARTBIT_LOGIC_0 (166e3 / TCB_TICK)
|
||||
#define AVCLAN_STARTBIT_LOGIC_1 (19e3 / TCB_TICK)
|
||||
|
||||
#define AVCLAN_BIT1_LOGIC_0 (20.5e3 / TCB_TICK)
|
||||
#define AVCLAN_BIT1_LOGIC_1 (19e3 / TCB_TICK)
|
||||
|
||||
#define AVCLAN_BIT0_LOGIC_0 (34e3 / TCB_TICK)
|
||||
#define AVCLAN_BIT0_LOGIC_1 (5.5e3 / TCB_TICK)
|
||||
|
||||
#define AVCLAN_READBIT_THRESHOLD (26e3 / TCB_TICK)
|
||||
|
||||
#define AVCLAN_BIT_LENGTH (39.5e3 / TCB_TICK)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user