/*
   What is missing ?

   Modify code so you can see oif a packet is transmitted or not
      hint: check return codes from Can 0/1  read/write

   What does the field "timeout " do in read and write
      hint. you can/shall set timeout field before writing. Can be 0 or 1
      hint. you shall set timeout flag before reading (in the packet you want to receive incomming packet)
*/




// -------------------------------------------------------------
// CANtest for Teensy 3.6 dual CAN bus
// by Collin Kidder, Based on CANTest by Pawelsky (based on CANtest by teachop)
//
// Both buses are left at default 250k speed and the second bus sends frames to the first
// to do this properly you should have the two buses linked together. This sketch
// also assumes that you need to set enable pins active. Comment out if not using
// enable pins or set them to your correct pins.
//
// This sketch tests both buses as well as interrupt driven Rx and Tx. There are only
// two Tx buffers by default so sending 5 at a time forces the interrupt driven system
// to buffer the final three and send them via interrupts. All the while all Rx frames
// are internally saved to a software buffer by the interrupt handler.
//

// Mod by JDN  (feb 2024 II)
#include <FlexCAN.h>

#ifndef __MK66FX1M0__
#error "Teensy 3.6 with dual CAN bus is required to run this example"
#endif

// CAN0 1 Mbit/sec
//ID 0  (pin 29,30)
// txAlternative  if 1 use std pin 29 else pin 3
// rxAlternative  if 1 usestd pin30, else pin 4
// -----------------------------------------------------
// CAN1 1 Mbit/sec
// ID 1  (pin 34,35)
// txAlternative  pin 33 - no alternative bq pins sre not broken out on teensy 3.6
// rxAlternative  pin 34 -  no alternative bq pins sre not broken out on teensy 3.6

FlexCAN Can0(100000, 0, 1, 1);

FlexCAN Can1(100000, 1, 1, 1);

static CAN_message_t msg0, msg1;
static uint8_t hex[17] = "0123456789abcdef";

// -------------------------------------------------------------
static void hexDump(uint8_t dumpLen, uint8_t *bytePtr) {
  uint8_t working;
  while (dumpLen--) {
    working = *bytePtr++;
    Serial.write(hex[working >> 4]);
    Serial.write(hex[working & 15]);
  }
  Serial.write('\r');
  Serial.write('\n');
}

int initCAN() {
  //Setting pin 35 / 28 low enables high speed mode on the two transceivers
  pinMode(28, OUTPUT);
  pinMode(35, OUTPUT);

  digitalWrite(28, LOW);
  digitalWrite(35, LOW);

  Can0.begin();
  Can1.begin();

  return 0;  // for future use
}

int fillStdTlg() {
  // fillin
  msg1.ext = 0;
  msg1.id = 0x100;
  msg1.len = 8;
  //msg1.timeout = 0; // timeout (in msec) is used when receiving. So before calling read you set timeout to 0,1,2,3 etc
  msg1.buf[0] = 10;
  msg1.buf[1] = 20;
  msg1.buf[2] = 0;
  msg1.buf[3] = 100;
  msg1.buf[4] = 128;
  msg1.buf[5] = 64;
  msg1.buf[6] = 32;
  msg1.buf[7] = 16;

  return 0;  // ok - for future use
}

// -------------------------------------------------------------
void setup(void) {
  delay(100);
  Serial.begin(57600);

  while (!Serial)
    ;  // wait
  Serial.println("cantest2");

  pinMode(13, OUTPUT);  // for blinking

  initCAN();
  fillStdTlg();


  Serial.println("bef start- wait two seconds");
  Serial.println(millis());
  delay(2000);

  // lert me throw the first packet for the ping-pong
  Can1.write(msg0);  // MISSING returns 1 if msg is delivered to CAN controller. 0 if not !!!
}


// -------------------------------------------------------------

void toggleLED13() {
  static boolean LED13 = false;
  if (LED13) {
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }
  LED13 = !LED13;
}

// just to slow down blink. Freq more than maybe 10 Hz -> you cant see blink
void toogleLEDSlow(int scale) {
  static int ccc = 0;
  ccc++;
  if (scale < ccc) {
    ccc = 0;
    toggleLED13();
  }
}


int can0Cnt = 0, can1Cnt=0;

int ret0 = 0, ret1 = 0;

void loop(void) {

  if (Can0.available()) {
    ret0 = Can0.read(msg1);  // did you receive anything ? returns 1 (ok) and 0 if no sucess
    if (ret0 == 1) {         // got a pkg
      can0Cnt++;
      Can0.write(msg0);  // MISSING returns 1 if msg is delivered to CAN controller. 0 if not !!!
      Serial.print("can0 ");
      Serial.println(can0Cnt);
    }
    toogleLEDSlow(1000);
  }


  if (Can1.available()) {
    ret1 = Can1.read(msg1);  // did you receive anything ?returns 1 (ok) and 0 if no sucess
    if (ret1 == 1) {         // got a pkg
      can1Cnt++;
      ret1 = Can1.write(msg1);  // MISSING returns 1 if msg is delivered to CAN controller. 0 if not !!!
      Serial.print("can1 ");
      Serial.println(can1Cnt);
    }
  }
}
