Created
October 6, 2020 19:34
-
-
Save jepler/cac560a28f44f16bdc8a442a9be5ed34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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