Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*----------------------------------------------------------------------------------------------------------------------------------
- * Name : AuxRancher.ino
- * Description : I hope this works and can talk to the CN702 12 pin jack
- * MCU : Arduino Nano from Banggood lol
- * Author : Bo Laurence Thompson
- * History : 2016-01-23 - v0.1 Prototyping draft heavily inspired by thew work of Louis Frigon, aka(?) SigmaObjects.
- *
- *
- # DON'T BE A DICK PUBLIC LICENSE
- > Version 1.1, December 2016
- > Copyright (C) [year] [fullname]
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document.
- > DON'T BE A DICK PUBLIC LICENSE
- > TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 1. Do whatever you like with the original work, just don't be a dick.
- Being a dick includes - but is not limited to - the following instances:
- 1a. Outright copyright infringement - Don't just copy this and change the name.
- 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
- 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
- 2. If you become rich through modifications, related works/services, or supporting the original work,
- share the love. Only a dick would make loads off this work and not buy the original work's
- creator(s) a pint.
- 3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
- you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
- ---------------------------------------------------------------------------------------------------------------------------------*/
- #include <avr/wdt.h>
- #define fwVer "v0.1"
- #define fwDt __DATE__
- #define ZERO_LENGTH 65
- #define ONE_LENGTH 38
- #define BIT_LENGTH 76
- #define START_BIT_ON_LENGTH 345
- #define START_BIT_LENGTH 382
- #define MSG_NORMAL 1
- #define MSG_BCAST 0
- #define HU_ADDR 0x190
- #define ALL_AUDIO_ADDR 0x1FF
- #define MY_ADDR 0x360
- #define UNKNOWN_ADDR 0xFFF
- #define DESCRIPTION_LENGTH 20
- bool ParityBit;
- bool bbit;
- word mAddr;
- word sAddr;
- byte cBits;
- byte dlnth;
- byte data[256];
- char descBuf[DESCRIPTION_LENGTH+1];
- typedef byte MessageID;
- enum {
- ACT_UNKNOWN,
- ACT_POWERON,
- ACT_POWEROFF,
- ACT_PASSIVEOFF_0,
- ACT_PASSIVEOFFRARE_0,
- ACT_PASSIVEONRARE,
- ACT_PASSIVEON_0,
- ACT_PRESSDISC,
- ACT_PRESSAM,
- ACT_STATIONFOUND,
- ACT_INIT,
- ACT_AM
- };
- struct MessageDef {
- MessageID ID;
- word MasterAddr;
- word SlaveAddr;
- byte PayloadLength;
- word Payload[24];
- char Description[DESCRIPTION_LENGTH];
- };
- const MessageDef MessageTable[] PROGMEM = {
- {ACT_POWERON, HU_ADDR, ALL_AUDIO_ADDR, 13, {0x00, 0x00, 0x00, 0x00, 0x100, 0x100, 0x00, 0x81, 0x100, 0x01, 0xF1, 0x31, 0x60}, "FM in use"},
- {ACT_POWEROFF, HU_ADDR, UNKNOWN_ADDR, 13, {0x00, 0x60, 0x31, 0xF1, 0x00, 0x00, 0x81, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00}, "off?"},
- {ACT_PASSIVEOFF_0, HU_ADDR, UNKNOWN_ADDR, 3, {0x46, 0x01, 0x11}, "Passive: Weak"},
- {ACT_PASSIVEOFFRARE_0, HU_ADDR, UNKNOWN_ADDR, 4, {0x60, 0x45, 0x01, 0x11}, "Passive: Strong"},
- {ACT_PASSIVEONRARE, HU_ADDR, UNKNOWN_ADDR, 4, {0x100, 0x20, 0x01, 0x11}, "Passive: Fierce"},
- {ACT_PASSIVEON_0, HU_ADDR, ALL_AUDIO_ADDR, 16, {0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x100, 0x80, 0xF1, 0x31, 0x74}, "Vol Knob"},
- {ACT_PRESSDISC, HU_ADDR, ALL_AUDIO_ADDR, 4, {0x00, 0x9F, 0x31, 0x62}, "No DISC available"},
- {ACT_PRESSAM, HU_ADDR, ALL_AUDIO_ADDR, 24, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x00, 0xCB, 0x00, 0xAF, 0x00, 0x69, 0x00, 0x37, 0x00, 0x03, 0x00}, "AM/FM Switch"},
- {ACT_STATIONFOUND, HU_ADDR, ALL_AUDIO_ADDR, 13, {0x00, 0x00, 0x00, 0x04, 0x00, 0x100, 0x00, 0x100, 0x100, 0x01, 0xF1, 0x31, 0x60}, "FM station found"},
- {ACT_INIT, HU_ADDR, UNKNOWN_ADDR, 3, {0x100, 0x01, 0x11}, "Init"},
- {ACT_AM, HU_ADDR, ALL_AUDIO_ADDR, 13, {0x00, 0x00, 0x00, 0x00, 0x100, 0x100, 0x00, 0x01, 0x01, 0x01, 0xF1, 0x31, 0x60}, "AM in use"}
- };
- const byte MessageTableSize = sizeof(MessageTable)/sizeof(MessageDef);
- //====================================================================================COPYPASTED
- #define DATAIN_PIN ACSR
- #define DATAIN ACO
- #define INPUT_IS_SET ( bit_is_set( DATAIN_PIN, DATAIN ) )
- #define INPUT_IS_CLEAR ( bit_is_clear( DATAIN_PIN, DATAIN ) )
- //===================================================================================WHAT DOES THIS MEAN
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- //============================================================================================================================================================================================================
- // Setup()
- // Runs once at PowerOn and whenever Reset is pushed.
- //============================================================================================================================================================================================================
- void setup() {
- TCCR1A = 0;
- TCCR1B = _BV(CS11);
- Serial.begin(9600);
- //pinMode(3,INPUT);
- //pinMode(2,INPUT);
- PORTD |= _BV(PD3); // PD3 (+) high.
- PORTD &= ~_BV(PD2); // PD2 (-) low.
- pinMode(LED_BUILTIN,OUTPUT);
- //DDRD |= _BV(PD2) | _BV(PD3);
- //two second watchdog
- wdt_enable( WDTO_2S );
- Serial.println("Toyota AuxRancher");
- Serial.println("By Bo Thompson");
- Serial.println("Firmware "+String(fwVer)+", compiled on "+fwDt);
- Serial.println("Known messages: " +String(MessageTableSize));
- LedOff();
- }
- //============================================================================================================================================================================================================
- // LedOn() and LedOff()
- // Just manages the Led a bit easier.
- //============================================================================================================================================================================================================
- void LedOff() {
- digitalWrite(LED_BUILTIN, LOW);
- }
- void LedOn() {
- digitalWrite(LED_BUILTIN, HIGH);
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- void SetOutputHigh() {
- DDRD |= _BV(PD2) | _BV(PD3);
- }
- void SetOutputLow() {
- pinMode(3,OUTPUT);
- pinMode(2,INPUT);
- }
- void ReleaseOutput() {
- DDRD &= ~( _BV(PD2) | _BV(PD3) );
- }
- //============================================================================================================================================================================================================
- // Loop()
- // Constantly running.
- //============================================================================================================================================================================================================
- void loop() {
- wdt_reset();
- /*while (INPUT_IS_CLEAR) wdt_reset();
- TCNT1=0;
- while (INPUT_IS_SET);
- Serial.println(String(TCNT1));*/
- if (ReadMessage()==1) {
- byte msgid =IdentifyMessage();
- if (msgid < MessageTableSize) {
- strncpy_P(descBuf, MessageTable[msgid].Description, DESCRIPTION_LENGTH);
- Serial.println(descBuf);
- if (pgm_read_byte_near(&MessageTable[msgid].ID) == ACT_PRESSDISC ){
- SendMessage();
- }
- }
- }
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- bool SendMessage() {
- while (!BusIsFree());
- LedOn();
- //begin
- SendStartBit();
- //broadcast bit
- Send1BitWord(0);
- //master address with parity
- Send12BitWord(MY_ADDR);
- Send1BitWord(ParityBit);
- //slave address with parity and ack
- Send12BitWord(HU_ADDR);
- Send1BitWord(ParityBit);
- if (!LeadAck()) {
- Serial.println("SendMessage: No Ack at Slave Address!");
- return false;
- }
- else Serial.println("SendMessage: Ack received");
- LedOff();
- return true;
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- bool BusIsFree() {
- while (INPUT_IS_SET) wdt_reset();
- TCNT1 = 0;
- while (TCNT1<BIT_LENGTH) {
- if (INPUT_IS_SET) return false;
- }
- return true;
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- bool LeadAck() {
- TCNT1 = 0;
- //drive a one
- DDRD |= _BV(PD2) | _BV(PD3);
- while (TCNT1 < ONE_LENGTH);
- //while (1) wdt_reset();
- //now shut up and listen
- DDRD &= ~( _BV(PD2) | _BV(PD3) );
- while(INPUT_IS_SET);
- //if we just waited for a zero length,
- if (TCNT1 > ONE_LENGTH+(ZERO_LENGTH-ONE_LENGTH)/2) {
- return true;
- }
- //otherwise, something is wrong.
- return false;
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- void SendStartBit() {
- TCNT1 = 0;
- //drive for the length of the start bit
- DDRD |= _BV(PD2) | _BV(PD3);
- while (TCNT1 < START_BIT_ON_LENGTH);
- //pull until the grace period is over
- DDRD &= ~( _BV(PD2) | _BV(PD3) );
- while (TCNT1 < START_BIT_LENGTH);
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- void Send1BitWord(bool data) {
- TCNT1 = 0;
- //drive for the length of one or zero
- DDRD |= _BV(PD2) | _BV(PD3);
- if (data) while (TCNT1 < ONE_LENGTH);
- else while(TCNT1 < ZERO_LENGTH);
- //pull until the bit is over
- DDRD &= ~( _BV(PD2) | _BV(PD3) );
- while (TCNT1 < BIT_LENGTH);
- }
- //============================================================================================================================================================================================================
- //
- //
- //============================================================================================================================================================================================================
- void Send12BitWord(word data) {
- ParityBit = 0;
- for (byte ii = 0; ii<12; ii++){
- TCNT1 = 0;
- DDRD |= _BV(PD2) | _BV(PD3);
- if (data & 0x0800) {
- ParityBit = !ParityBit;
- while (TCNT1<ONE_LENGTH);
- }
- else {
- while (TCNT1<ZERO_LENGTH);
- }
- DDRD &= ~( _BV(PD2) | _BV(PD3) );
- data<=1;
- while (TCNT1<BIT_LENGTH);
- }
- }
- //============================================================================================================================================================================================================
- // ReadMessage()
- // Returns a boolean, 1 if it works and 0 if there is some kind of error. Usually parity.
- // Also sets the global variables for the message information read.
- // Happens once per loop.
- //============================================================================================================================================================================================================
- bool ReadMessage() {
- //start bit
- ReadBits(1);
- LedOn();
- //broadcast bit
- bbit = ReadBits(1);
- //master address
- mAddr = ReadBits(12);
- //handle parity
- if (ParityBit!=ReadBits(1)){
- Serial.println("ReadMessage: Parity error at Master Address!");
- return(0);
- }
- //Slave Address
- sAddr = ReadBits(12);
- if (ParityBit!=ReadBits(1)) {
- Serial.println("ReadMessage: Parity error at Slave Address!");
- return(0);
- }
- ReadBits(1);
- //control bits
- cBits = ReadBits(4);
- if (ParityBit!=ReadBits(1)) {
- Serial.println("ReadMessage: Parity error at Control Bits!");
- return(0);
- }
- ReadBits(1);
- //payload length
- dlnth = ReadBits(8);
- if (ParityBit!=ReadBits(1)) {
- Serial.println("ReadMessage: Parity error at Payload Length!");
- return(0);
- }
- ReadBits(1);
- //data loop
- byte ii = dlnth;
- while (ii-->0) {
- data[ii]=ReadBits(8);
- if (ParityBit!=ReadBits(1)){
- Serial.println("ReadMessage: Parity error at Data "+String(ii)+"!");
- return(0);
- }
- ReadBits(1);
- }
- LedOff();
- return 1;
- }
- //============================================================================================================================================================================================================
- // Readbits()
- // Takes a byte as input for the number of bits to read. Returns a word for the data recorded.
- // This is used many times for each incoming message we read.
- // Also sets the global variable ParityBit to whatever the expected parity value for these bits is.
- //============================================================================================================================================================================================================
- word ReadBits(byte nbits) {
- word data = 0; //this will be the word we record and return
- ParityBit=0; //parity tracking
- while (nbits-->0) { //for each bit we must capture:
- data<<=1; //shift data left 1 bit
- while(INPUT_IS_CLEAR) wdt_reset(); //wait for a pulse
- TCNT1=0; //measure pulse
- while(INPUT_IS_SET); //wait for the end of the pulse
- if (TCNT1<ZERO_LENGTH-(ZERO_LENGTH-ONE_LENGTH)/2) { //if that was less than the half way mark between zero and one,
- data |= 1; //tack on a one
- ParityBit = !ParityBit; //adjust parity
- }
- }
- return data;
- }
- //============================================================================================================================================================================================================
- // DumpMessage()
- // Dumps the contents of the last message read.
- // This only happens when we encounter a message we aren't familiar with.
- //============================================================================================================================================================================================================
- void DumpMessage() {
- //Serial.println("==============================================");
- Serial.print("Master address: ");
- Serial.print("0x"); Serial.println(mAddr,HEX);
- Serial.print("Slave address: ");
- Serial.print("0x"); Serial.println(sAddr,HEX);
- Serial.print("Control bits: ");
- Serial.print("B"); Serial.println(cBits,BIN);
- Serial.print("Data length: ");
- Serial.println(dlnth);
- for (byte ii=0; ii<dlnth; ii++){
- Serial.print("0x"); if (data[ii]<16) Serial.print("0");
- Serial.print(data[ii],HEX);
- Serial.print(", ");
- }
- Serial.println();
- Serial.println("==============================================");
- }
- //============================================================================================================================================================================================================
- // IdentifyMessage()
- // Determines the type of message we have captured.
- // Returns MessageID for the purpose of taking the action that message calls for.
- //
- //============================================================================================================================================================================================================
- byte IdentifyMessage() {
- bool match = false;
- byte i;
- for (i=0; i<MessageTableSize; i++) {
- //compare data sizes
- //if size matches, begin comparing data
- if ((pgm_read_byte_near(&MessageTable[i].PayloadLength)==dlnth) and (pgm_read_word_near(&MessageTable[i].MasterAddr)==mAddr) and (pgm_read_word_near(&MessageTable[i].SlaveAddr)==sAddr)) {
- match = true;
- for (byte ii=0; ii<dlnth; ii++) {
- //if comparison data in place ii is variable,
- if (pgm_read_word_near(&MessageTable[i].Payload[ii])>0xFF) {
- continue;
- }
- //compare data in place ii
- //if data doesn't match, set match to false
- if (pgm_read_word_near(&MessageTable[i].Payload[ii]) != data[ii]) {
- match = false;
- break;
- }
- }
- }
- //if match is still set to true after comparing all data, return the place in the table to which our message belongs
- if (match) return(i);
- }
- Serial.println("===============Unknown=Message================");
- DumpMessage();
- return(i);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement