2

I'm attempting to copycat the work of Louis Frigon's Toyota Aux Enabler. I have (with a lot of help on this site) managed to begin capturing and understanding messages on the AVC-LAN bus, but I can't quite send messages. Frigon uses the following line to drive output signal to high:

DDRD |= _BV(PD2) | _BV(PD3);

I have more or less no idea what this means. He then 'releases the output' with the following:

DDRD &= ~( _BV(PD2) | _BV(PD3) );

If I copy these lines verbatim I don't get the same results. If I set the output high and then read the bus, I don't even see the signal I'm putting out. I wonder if this is related to the differences between his Atmega8 and my Arduino Nano?

I can't paste my or Frigon's work here due to character count limitations, so here is his github for the project: https://github.com/halleysfifthinc/Toyota-AVC-LAN

The most important files to my question are BigSchematic.jpg and AVCLanDriver.c.

Here is a dump of my current code: https://pastebin.com/NG9U5FuL

Here is my schematic: https://i.sstatic.net/csiVv.jpg

1
  • I give you +1 for the your work investigating your problem.
    – user31481
    Commented Jan 29, 2018 at 9:12

1 Answer 1

1

Each port on the ATmega328P (or the ATmega8 for that matter) is controlled by two registers¹:

  • DDRx, where x is B, C or D, is the “data direction register”. It is used to set the pin to either input or output. Writing to this register is roughly equivalent to calling pinMode().
  • PORTx is the port's “data register”. It is mostly used in output mode to set the pin to HIGH or LOW. Writing to this register is equivalent to calling digitalWrite().

All this is covered by the Arduino tutorial on direct port access. And, of course, by the datasheet; more specifically by section 18.2: “Ports as General Digital I/O”.

As you may now notice, the original code does not use anything like digitalWrite() to write to the bus, relying instead of the equivalent of pinMode(). This is related to the electrical characteristics of the bus:

  • You write a “physical 1” by actively driving AVC+ high and AVC− low
  • You write a “physical 0” by releasing the bus, in which case the potentials of those lines are set by the termination resistors.

That's why you see InitMCU() setting PORTD for driving AVC+ high and AVC− low, but leaving DDRD in its initial state (“leave pins tri-stated” says the comment). At this point the bus is in the “released” state. Then pulses are sent by setting the pins to output mode (“Drive output to signal high” in the comment) and, after an appropriate delay, setting them back to input mode (“Release output”).


¹ I am leaving away the details that are irrelevant to the code in question, like the internal pullup or pin toggling via PINx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.