talon/User/can.c
2024-01-13 12:57:51 -05:00

69 lines
2.3 KiB
C

#include "can.h"
u8 can_init() {
// Enable CAN1 peripheral
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
// Enable AFIORCC_APB2Periph_AFIO | GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
// Set up GPIO on port A
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// CAN1_RX - PA11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// CAN1_TX - PA12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Disable filters so we can actually receive things
CAN_FilterInitTypeDef CAN_FilterInitStruct;
CAN_FilterInitStruct.CAN_FilterNumber = 0;
CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStruct.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStruct);
// Init the can controller, set baud rate to 1Mbps
// Formula for baud:
// SysClk = 72MHz
// AHB = 72MHz
// APB1 = AHB / 2 = 36MHz
// Bitrate = APB1 / ((BS1 + BS2 + 1) * Prescaler)
// 1Mbaud = 36MHz / ((14 + 3 + 1) * 2)
//
// Other values that work, BS1=5, BS2=3, Div=4
// For now I use values that are as close to CTRE's candle light code
CAN_InitTypeDef CAN_InitStructure;
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_Prescaler = 4;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
return CAN_Init(CAN1, &CAN_InitStructure);
}
u8 can_recv(CanRxMsg *RxMessage) {
u8 got_msg = 0;
if(CAN_MessagePending(CAN1, CAN_FIFO0)) {
CAN_Receive(CAN1, CAN_FIFO0, RxMessage);
got_msg = 1;
} else if(CAN_MessagePending(CAN1, CAN_FIFO1)) {
CAN_Receive(CAN1, CAN_FIFO1, RxMessage);
got_msg = 1;
}
return got_msg;
}