Skip to content

Instantly share code, notes, and snippets.

@jepler
Created October 6, 2020 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jepler/cac560a28f44f16bdc8a442a9be5ed34 to your computer and use it in GitHub Desktop.
Save jepler/cac560a28f44f16bdc8a442a9be5ed34 to your computer and use it in GitHub Desktop.
#include "wiring_private.h"
#include <sam.h>
#include <component/can.h>
#include <component/gclk.h>
#include <instance/can0.h>
#include <instance/gclk.h>
#define GCLK_CAN GCLK_PCHCTRL_GEN_GCLK1_Val
#define FREQ VARIANT_GCLK1_FREQ
struct can_tx_buf {
CAN_TXBE_0_Type txb0;
CAN_TXBE_1_Type txb1;
__attribute__((aligned(4)))
uint8_t data[8];
};
__attribute__((section("canram")))
can_tx_buf tx_buffer;
#define CAN_RX_PIN (15)
#define CAN_TX_PIN (14)
#define CAN_GROUP (1)
#define CAN_FUNCTION ((EPioType)7)
// the setup function runs once when you press reset or power the board
void setup() {
pinPeripheral(41, CAN_FUNCTION);
pinPeripheral(42, CAN_FUNCTION);
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_CAN | (1 << GCLK_PCHCTRL_CHEN_Pos);
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_CAN | (1 << GCLK_PCHCTRL_CHEN_Pos);
// reset and allow configuration change
CAN1->CCCR.bit.INIT = 1;
while (!CAN1->CCCR.bit.INIT) {
}
CAN1->CCCR.bit.CCE = 1;
CAN1->MRCFG.reg = 0;
{
CAN_CCCR_Type cccr = {};
cccr.bit.CCE = 1;
cccr.bit.TEST = 1;
CAN1->CCCR.reg = cccr.reg;
}
// 1MHz
{
CAN_DBTP_Type dbtp = {};
dbtp.bit.DBRP = 0;
dbtp.bit.DTSEG1 = 40-2;
dbtp.bit.DTSEG2 = 8-1;
dbtp.bit.DSJW = 3;
CAN1->DBTP.reg = dbtp.reg;
}
{
CAN_TEST_Type test = {};
// test.bit.LBCK = 1,
CAN1->TEST.reg = test.reg;
}
// 1MHz
{
CAN_NBTP_Type nbtp;
nbtp.bit.NBRP = 0;
nbtp.bit.NTSEG1 = 40-2;
nbtp.bit.NTSEG2 = 8-1;
nbtp.bit.NSJW = 3;
CAN1->NBTP.reg = nbtp.reg;
}
// max 8 byte payload
{
CAN_TXESC_Type esc = {};
esc.bit.TBDS = CAN_TXESC_TBDS_DATA8_Val;
CAN1->TXESC.reg = esc.reg;
}
{
CAN_TXBC_Type bc = {};
bc.bit.TBSA = (uint32_t)&tx_buffer,
bc.bit.NDTB = 1;
bc.bit.TFQM = 0; // Messages are transmitted in the order submitted
CAN1->TXBC.reg = bc.reg;
}
CAN1->CCCR.bit.CCE = 0;
CAN1->CCCR.bit.INIT = 0;
while(CAN1->CCCR.bit.INIT) {
}
Serial.begin(9600); // open the serial port at 9600 bps:
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
static uint64_t i = 0;
// the loop function runs over and over again forever
void loop() {
Serial.print("CAN hardware info\n");
Serial.print("Version ");
Serial.print(CAN1->CREL.bit.REL);
Serial.print(".");
Serial.print(CAN1->CREL.bit.STEP);
Serial.print(".");
Serial.print(CAN1->CREL.bit.SUBSTEP);
Serial.println("\n");
i = i + 1;
Serial.println((long)i, HEX);
memcpy(&tx_buffer.data, &i, sizeof(tx_buffer.data));
tx_buffer.txb0.bit.ID = 0x408 << 18;
tx_buffer.txb1.bit.DLC = 8;
Serial.print("CAN ECR x");
Serial.println(CAN1->ECR.reg, HEX);
Serial.print("CAN PSR x");
Serial.println(CAN1->PSR.reg, HEX);
if(CAN1->PSR.bit.BO) {
Serial.println("Manual reset");
CAN1->CCCR.bit.INIT = 0;
while(CAN1->CCCR.bit.INIT) {
}
}
CAN1->TXBAR.reg = 1;
for(int i=0; (CAN1->TXBTO.reg & 1) && (i<8); i++) {
delay(1); // wait for message to transmit
}
Serial.print("CAN TXBTO x");
Serial.println(CAN1->TXBTO.reg, HEX);
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment