16static void _CAN_init(CAN_TypeDef *,
CAN_Config *);
32 if (interface == NULL)
33 return (
CAN_t){.interface = NULL};
36 CAN_t can = {.interface = interface};
39 CAN_updateConfig(&can, config);
42 can.transmit = CAN_transmit;
43 can.receive = CAN_receive;
44 can.updateConfig = CAN_updateConfig;
64static void _CAN_init(CAN_TypeDef *interface,
CAN_Config *config) {
82 volatile uint32_t *fifo = (can->interface == CAN1) ? &CAN1->RF0R : &CAN2->RF1R;
83 uint8_t nFifo = (can->interface == CAN1) ? 0 : 1;
85 if (*fifo & CAN_RF0R_FMP0) {
87 rxData->id = (can->interface->sFIFOMailBox[nFifo].RIR & 0xFFE00040) >> 21;
88 rxData->data[0] = can->interface->sFIFOMailBox[nFifo].RDLR;
89 rxData->data[0] = can->interface->sFIFOMailBox[nFifo].RDHR;
93 *fifo &= ~CAN_RF0R_FOVR0;
94 *fifo &= ~CAN_RF0R_FULL0;
113 bool mailboxFree = can->interface->TSR & (0b111 << CAN_TSR_TME0_Pos);
117 uint8_t mailbox = (can->interface->TSR & CAN_TSR_CODE_Msk) >> CAN_TSR_CODE_Pos;
120 can->interface->sTxMailBox[mailbox].TDHR = txData->data[1];
121 can->interface->sTxMailBox[mailbox].TDLR = txData->data[0];
122 can->interface->sTxMailBox[mailbox].TDTR = txData->length;
125 can->interface->sTxMailBox[mailbox].TIR =
126 (txData->id <= CAN_STID_MAX)
127 ? (txData->id << CAN_TI0R_STID_Pos)
128 : (txData->id << CAN_TI0R_EXID_Pos);
131 can->interface->sTxMailBox[mailbox].TIR |= CAN_TI0R_TXRQ;
135 if (can->interface->TSR & CAN_TSR_TXOK0)
137 else if (can->interface->TSR & CAN_TSR_TERR0) {
138 can->interface->TSR |= CAN_TSR_ABRQ0;
159 if (config == NULL) {
164 can->config = *config;
167 _CAN_init(can->interface, config);
172void CANGPIO_config() {
180void CAN_Peripheral_config() {
181 CAN1->MCR |= CAN_MCR_RESET;
182 while (CAN1->MCR & CAN_MCR_RESET);
184 CAN1->MCR &= ~CAN_MCR_SLEEP;
185 while (CAN1->MSR & CAN_MSR_SLAK);
187 CAN1->MCR |= CAN_MCR_INRQ;
188 while (!(CAN1->MSR & CAN_MSR_INAK));
190 CAN1->BTR &= (uint32_t)~(0xC37F03FF);
191 CAN1->BTR |= 0x003f000f;
192 CAN1->MCR |= (CAN_MCR_ABOM | CAN_MCR_AWUM);
195 CAN1->FM1R &= (uint32_t)~(0x1);
197 CAN1->FA1R &= 0xF0000000;
199 CAN1->sFilterRegister[0].FR1 = 0;
200 CAN1->sFilterRegister[0].FR2 = 0;
203 CAN1->FMR &= (uint32_t)~(0x1);
205 CAN1->MCR &= ~CAN_MCR_INRQ;
206 while (CAN1->MSR & CAN_MSR_INAK);
208 CAN1->IER |= CAN_IER_FMPIE0;
GPIO_Mode mode
Pin I/O direction | (default GPIO_MODE_OUTPUT)
GPIO_AF afr
Pin alternate function | (default GPIO_AF0)
GPIOpin_t GPIOpin_init(GPIO_TypeDef *, GPIO_Pin, GPIO_Config *)
Initialiser for a GPIO peripheral pin interface.
@ GPIO_AF9
CAN1/CAN2, LTDC, TIM12..14.
@ GPIO_MODE_AF
Alternate function mode.
Struct definition for GPIO configuration.