/** Config the CAN mode . * * @param can_periph CAN0 or CAN1. * @param mode the mode to be set. */ static void dev_can_mode_config(uint32_t can_periph, uint32_t mode) { /* enter the initialization mode, only in initialization mode CAN register can be configured */ can_working_mode_set(can_periph, CAN_MODE_INITIALIZE); CAN_BT(can_periph) &= ~BT_MODE(3); CAN_BT(can_periph) |= BT_MODE(mode); /* enter the normal mode */ can_working_mode_set(can_periph, CAN_MODE_NORMAL); }
/*! \brief initialize CAN \param[in] can_periph \arg CANx(x=0,1),the CAN1 only for GD32F30X_CL \param[in] can_parameter_init: parameters for CAN initializtion \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) \arg time_segment_1: CAN_BT_BS1_xTQ(1..16) \arg time_segment_2: CAN_BT_BS2_xTQ(1..8) \arg time_triggered: ENABLE or DISABLE \arg auto_bus_off_recovery: ENABLE or DISABLE \arg auto_wake_up: ENABLE or DISABLE \arg auto_retrans: ENABLE or DISABLE \arg rec_fifo_overwrite: ENABLE or DISABLE \arg trans_fifo_order: ENABLE or DISABLE \arg prescaler: 0x0001 - 0x03FF \param[out] none \retval ErrStatus: SUCCESS or ERROR */ ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) { uint32_t timeout = CAN_TIMEOUT; ErrStatus flag = ERROR; /* disable sleep mode */ CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; /* enable initialize mode */ CAN_CTL(can_periph) |= CAN_CTL_IWMOD; /* wait ACK */ while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ timeout--; } /* check initialize working success */ if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ flag = ERROR; }else{ /* set the bit timing register */ CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \ BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \ BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); /* time trigger communication mode */ if(ENABLE == can_parameter_init->time_triggered){ CAN_CTL(can_periph) |= CAN_CTL_TTC; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_TTC; } /* automatic bus-off managment */ if(ENABLE == can_parameter_init->auto_bus_off_recovery){ CAN_CTL(can_periph) |= CAN_CTL_ABOR; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; } /* automatic wakeup mode */ if(ENABLE == can_parameter_init->auto_wake_up){ CAN_CTL(can_periph) |= CAN_CTL_AWU; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_AWU; } /* automatic retransmission mode */ if(ENABLE == can_parameter_init->auto_retrans){ CAN_CTL(can_periph) |= CAN_CTL_ARD; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_ARD; } /* receive fifo overwrite mode */ if(ENABLE == can_parameter_init->rec_fifo_overwrite){ CAN_CTL(can_periph) |= CAN_CTL_RFOD; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; } /* transmit fifo order */ if(ENABLE == can_parameter_init->trans_fifo_order){ CAN_CTL(can_periph) |= CAN_CTL_TFO; }else{ CAN_CTL(can_periph) &= ~CAN_CTL_TFO; } /* disable initialize mode */ CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; timeout = CAN_TIMEOUT; /* wait the ACK */ while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ timeout--; } /* check exit initialize mode */ if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){ flag = SUCCESS; } } return flag; }