2022-11-29 15:56:43 -08:00
// Flasher and pedal use raw mailbox access
# define GET_MAILBOX_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0xFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
# define GET_MAILBOX_BYTES_04(msg) ((msg)->RDLR)
# define GET_MAILBOX_BYTES_48(msg) ((msg)->RDHR)
2022-09-12 14:31:22 -07:00
// SAE 2284-3 : minimum 16 tq, SJW 3, sample point at 81.3%
# define CAN_QUANTA 16U
# define CAN_SEQ1 12U
# define CAN_SEQ2 3U
# define CAN_SJW 3U
2019-05-21 08:11:38 -07:00
2022-09-12 14:31:22 -07:00
# define CAN_PCLK 48000U
2019-05-21 08:11:38 -07:00
// 333 = 33.3 kbps
// 5000 = 500 kbps
2019-07-04 01:04:58 -07:00
# define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10U / (x))
2019-05-21 08:11:38 -07:00
2020-04-13 20:32:53 -07:00
# define CAN_NAME_FROM_CANIF(CAN_DEV) (((CAN_DEV)==CAN1) ? "CAN1" : (((CAN_DEV) == CAN2) ? "CAN2" : "CAN3"))
2019-07-03 20:48:02 -07:00
void puts ( const char * a ) ;
2022-09-16 23:51:55 -07:00
// kbps multiplied by 10
const uint32_t speeds [ ] = { 100U , 200U , 500U , 1000U , 1250U , 2500U , 5000U , 10000U } ;
const uint32_t data_speeds [ ] = { 0U } ; // No separate data speed, dummy
2019-07-07 22:19:02 -07:00
bool llcan_set_speed ( CAN_TypeDef * CAN_obj , uint32_t speed , bool loopback , bool silent ) {
2020-04-13 20:32:53 -07:00
bool ret = true ;
2019-05-21 08:11:38 -07:00
// initialization mode
2019-12-05 14:19:29 -08:00
register_set ( & ( CAN_obj - > MCR ) , CAN_MCR_TTCM | CAN_MCR_INRQ , 0x180FFU ) ;
2020-04-13 20:32:53 -07:00
uint32_t timeout_counter = 0U ;
while ( ( CAN_obj - > MSR & CAN_MSR_INAK ) ! = CAN_MSR_INAK ) {
// Delay for about 1ms
delay ( 10000 ) ;
timeout_counter + + ;
if ( timeout_counter > = CAN_INIT_TIMEOUT_MS ) {
puts ( CAN_NAME_FROM_CANIF ( CAN_obj ) ) ; puts ( " set_speed timed out (1)! \n " ) ;
ret = false ;
2020-04-20 17:07:47 -07:00
break ;
2020-04-13 20:32:53 -07:00
}
2019-05-21 08:11:38 -07:00
}
2020-04-13 20:32:53 -07:00
if ( ret ) {
// set time quanta from defines
2022-09-12 14:31:22 -07:00
register_set ( & ( CAN_obj - > BTR ) , ( ( CAN_BTR_TS1_0 * ( CAN_SEQ1 - 1U ) ) |
( CAN_BTR_TS2_0 * ( CAN_SEQ2 - 1U ) ) |
( CAN_BTR_SJW_0 * ( CAN_SJW - 1U ) ) |
( can_speed_to_prescaler ( speed ) - 1U ) ) , 0xC37F03FFU ) ;
2020-04-13 20:32:53 -07:00
// silent loopback mode for debugging
if ( loopback ) {
register_set_bits ( & ( CAN_obj - > BTR ) , CAN_BTR_SILM | CAN_BTR_LBKM ) ;
}
if ( silent ) {
register_set_bits ( & ( CAN_obj - > BTR ) , CAN_BTR_SILM ) ;
}
// reset
register_set ( & ( CAN_obj - > MCR ) , CAN_MCR_TTCM | CAN_MCR_ABOM , 0x180FFU ) ;
timeout_counter = 0U ;
while ( ( ( CAN_obj - > MSR & CAN_MSR_INAK ) = = CAN_MSR_INAK ) ) {
// Delay for about 1ms
delay ( 10000 ) ;
timeout_counter + + ;
if ( timeout_counter > = CAN_INIT_TIMEOUT_MS ) {
puts ( CAN_NAME_FROM_CANIF ( CAN_obj ) ) ; puts ( " set_speed timed out (2)! \n " ) ;
ret = false ;
2020-04-20 17:07:47 -07:00
break ;
2020-04-13 20:32:53 -07:00
}
}
2019-05-21 08:11:38 -07:00
}
2019-06-26 14:47:06 -07:00
return ret ;
2019-05-21 08:11:38 -07:00
}
2020-04-13 20:32:53 -07:00
bool llcan_init ( CAN_TypeDef * CAN_obj ) {
bool ret = true ;
2019-12-05 14:19:29 -08:00
// Enter init mode
register_set_bits ( & ( CAN_obj - > FMR ) , CAN_FMR_FINIT ) ;
2020-03-05 00:16:03 -08:00
2019-12-05 14:19:29 -08:00
// Wait for INAK bit to be set
2020-04-13 20:32:53 -07:00
uint32_t timeout_counter = 0U ;
while ( ( ( CAN_obj - > MSR & CAN_MSR_INAK ) = = CAN_MSR_INAK ) ) {
// Delay for about 1ms
delay ( 10000 ) ;
timeout_counter + + ;
if ( timeout_counter > = CAN_INIT_TIMEOUT_MS ) {
puts ( CAN_NAME_FROM_CANIF ( CAN_obj ) ) ; puts ( " initialization timed out! \n " ) ;
ret = false ;
2020-04-20 17:07:47 -07:00
break ;
2020-04-13 20:32:53 -07:00
}
2019-05-21 08:11:38 -07:00
}
2020-06-03 15:08:57 -07:00
2020-04-13 20:32:53 -07:00
if ( ret ) {
// no mask
// For some weird reason some of these registers do not want to set properly on CAN2 and CAN3. Probably something to do with the single/dual mode and their different filters.
CAN_obj - > sFilterRegister [ 0 ] . FR1 = 0U ;
CAN_obj - > sFilterRegister [ 0 ] . FR2 = 0U ;
CAN_obj - > sFilterRegister [ 14 ] . FR1 = 0U ;
CAN_obj - > sFilterRegister [ 14 ] . FR2 = 0U ;
CAN_obj - > FA1R | = 1U | ( 1U < < 14 ) ;
// Exit init mode, do not wait
register_clear_bits ( & ( CAN_obj - > FMR ) , CAN_FMR_FINIT ) ;
// enable certain CAN interrupts
2022-09-15 13:04:10 -07:00
register_set_bits ( & ( CAN_obj - > IER ) , CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_ERRIE | CAN_IER_LECIE | CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE | CAN_IER_FOVIE0 | CAN_IER_FFIE0 ) ;
2020-04-13 20:32:53 -07:00
if ( CAN_obj = = CAN1 ) {
NVIC_EnableIRQ ( CAN1_TX_IRQn ) ;
NVIC_EnableIRQ ( CAN1_RX0_IRQn ) ;
NVIC_EnableIRQ ( CAN1_SCE_IRQn ) ;
} else if ( CAN_obj = = CAN2 ) {
NVIC_EnableIRQ ( CAN2_TX_IRQn ) ;
NVIC_EnableIRQ ( CAN2_RX0_IRQn ) ;
NVIC_EnableIRQ ( CAN2_SCE_IRQn ) ;
# ifdef CAN3
} else if ( CAN_obj = = CAN3 ) {
NVIC_EnableIRQ ( CAN3_TX_IRQn ) ;
NVIC_EnableIRQ ( CAN3_RX0_IRQn ) ;
NVIC_EnableIRQ ( CAN3_SCE_IRQn ) ;
# endif
} else {
puts ( " Invalid CAN: initialization failed \n " ) ;
}
}
return ret ;
2019-05-21 08:11:38 -07:00
}
2019-07-07 22:19:02 -07:00
void llcan_clear_send ( CAN_TypeDef * CAN_obj ) {
2022-09-15 13:04:10 -07:00
CAN_obj - > TSR | = CAN_TSR_ABRQ0 ; // Abort message transmission on error interrupt
CAN_obj - > MSR | = CAN_MSR_ERRI ; // Clear error interrupt
2019-05-21 08:13:58 -07:00
}