/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_flexcan_io_init * Returned Value : 0 or 1 for success, -1 for failure * Comments : * This function performs BSP-specific initialization related to FLEXCAN * *END*----------------------------------------------------------------------*/ _mqx_int _bsp_flexcan_io_init ( uint_8 dev_num ) { volatile CAN_MemMapPtr can_reg_ptr; SIM_MemMapPtr sim = SIM_BASE_PTR; PORT_MemMapPtr pctl; OSC_CR |= OSC_CR_ERCLKEN_MASK; switch (dev_num) { case 0: /* Configure GPIO for FlexCAN 0 peripheral function */ pctl = (PORT_MemMapPtr)PORTA_BASE_PTR; pctl->PCR[12] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN0_TX.A12 */ pctl->PCR[13] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN0_RX.A13 */ /* Alternate GPIO pins for FlexCAN 0 peripheral function */ //pctl = (PORT_MemMapPtr)PORTB_BASE_PTR; //pctl->PCR[18] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN0_TX.B18 */ //pctl->PCR[19] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN0_RX.B19 */ /* Enable clock gate to FlexCAN 0 module */ sim->SCGC6 |= SIM_SCGC6_FLEXCAN0_MASK; /* Select the bus clock as CAN engine clock source */ can_reg_ptr = _bsp_get_flexcan_base_address (0); can_reg_ptr->CTRL1 |= CAN_CTRL1_CLKSRC_MASK; break; case 1: /* Configure GPIO for FlexCAN 1 peripheral function */ pctl = (PORT_MemMapPtr)PORTE_BASE_PTR; pctl->PCR[24] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN1_TX.E24 */ pctl->PCR[25] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN1_RX.E25 */ /* Alternate GPIO pins for FlexCAN 1 peripheral function */ //pctl = (PORT_MemMapPtr)PORTC_BASE_PTR; //pctl->PCR[17] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN1_TX.C17 */ //pctl->PCR[16] = (PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK); /* CAN1_RX.C16 */ /* Enable clock gate to FlexCAN 1 module */ sim->SCGC3 |= SIM_SCGC3_FLEXCAN1_MASK; /* Select the bus clock as CAN engine clock source */ can_reg_ptr = _bsp_get_flexcan_base_address (1); can_reg_ptr->CTRL1 |= CAN_CTRL1_CLKSRC_MASK; break; default: return -1; } return 0; }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_Install_isr_wake_int * Returned Value : uint32_t * Comments : * This function installs interrupt handler for a flexcan wake-up * *END*********************************************************************/ uint32_t FLEXCAN_Install_isr_wake_int ( /* [IN] FlexCAN device number */ uint8_t dev_num, /* [IN] Interrupt service routine */ INT_ISR_FPTR isr ) { uint32_t return_code = FLEXCAN_OK; INT_ISR_FPTR result; volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; volatile PSP_INTERRUPT_TABLE_INDEX index; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_WAKEUP, 0); if (0 == index) { return (FLEXCAN_INT_INSTALL_FAILED); } result = _int_install_isr (index, isr, (void *)can_reg_ptr); if(result == (INT_ISR_FPTR)NULL) { return_code = _task_get_error(); } return return_code; }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_int_status * Returned Value : uint32_t * Comments : * This function gets the FlexCAN interrupt status. * *END*********************************************************************/ uint32_t FLEXCAN_Int_status ( /* [IN] FlexCAN device number */ uint8_t dev_num ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; volatile uint32_t tmp_reg; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } // check Tx/Rx interrupt flag tmp_reg = (can_reg_ptr->IFLAG & FLEXCAN_IMASK_VALUE); if(tmp_reg) { return (uint32_t)(FLEXCAN_TX_RX_INT); } // check error interrupt tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_ERROR_INT); if(tmp_reg) { return (FLEXCAN_ERROR_INT); } // check busoff interrupt tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_BUSOFF_INT); if(tmp_reg) { return (FLEXCAN_BUSOFF_INT); } // check busoff interrupt tmp_reg = (can_reg_ptr->ERRSTAT & FLEXCAN_WAKEUP_INT); if(tmp_reg) { return (FLEXCAN_WAKEUP_INT); } return (FLEXCAN_OK); }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_Install_isr_ex * Returned Value : uint32_t * Comments : * This function installs interrupt handler for requested mailbox * *END*********************************************************************/ uint32_t FLEXCAN_Install_isr_ex ( /* [IN] FlexCAN device number */ uint8_t dev_num, /* [IN] mailbox number */ uint32_t mailbox_number, /* [IN] Interrupt service routine */ INT_ISR_FPTR isr, /* [IN] Interrupt service routine */ void *isr_data ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; uint32_t return_code = FLEXCAN_OK; INT_ISR_FPTR result; volatile PSP_INTERRUPT_TABLE_INDEX index; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) { return (FLEXCAN_INVALID_MAILBOX); } index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number); if (0 == index) { return (FLEXCAN_INT_INSTALL_FAILED); } /* Install ISR */ result = _int_install_isr (index, isr, (void *)isr_data); if(result == (INT_ISR_FPTR)NULL) { return_code = _task_get_error(); } return return_code; }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_Error_int_enable * Returned Value : uint32_t * Comments : * This function unmasks (enables) error, wake up & Bus off interrupts. * * *END*********************************************************************/ uint32_t FLEXCAN_Error_int_enable ( /* [IN] FlexCAN device number */ uint8_t dev_num ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; volatile PSP_INTERRUPT_TABLE_INDEX index; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_ERR, 0); if (0 == index) { return (FLEXCAN_INT_ENABLE_FAILED); } if (_flexcan_int_init (index, FLEXCAN_ERROR_INT_LEVEL, FLEXCAN_ERROR_INT_SUBLEVEL, TRUE) != MQX_OK) { return (FLEXCAN_INT_ENABLE_FAILED); } index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BOFF, 0); if (0 == index) { return (FLEXCAN_INT_ENABLE_FAILED); } if (_flexcan_int_init (index, FLEXCAN_BUSOFF_INT_LEVEL, FLEXCAN_BUSOFF_INT_SUBLEVEL, TRUE) != MQX_OK) { return (FLEXCAN_INT_ENABLE_FAILED); } /* BOFFMSK = 0x1, ERRMSK = 0x1 */ can_reg_ptr->CANCTRL |= (FLEXCAN_CANCTRL_BOFFMSK | FLEXCAN_CANCTRL_ERRMSK); return ( FLEXCAN_OK ); }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_Install_isr * Returned Value : uint32_t * Comments : * This function installs interrupt handler for requested mailbox * *END*********************************************************************/ uint32_t FLEXCAN_Install_isr ( /* [IN] FlexCAN device number */ uint8_t dev_num, /* [IN] mailbox number */ uint32_t mailbox_number, /* [IN] Interrupt service routine */ INT_ISR_FPTR isr ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } return FLEXCAN_Install_isr_ex(dev_num, mailbox_number, isr, (void *) can_reg_ptr); }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_int_disable * Returned Value : uint32_t * Comments : * This function masks (disables) interrupt for requested mailbox * *END*********************************************************************/ uint32_t FLEXCAN_Int_disable ( /* [IN] FlexCAN device number */ uint8_t dev_num, /* [IN] mailbox number */ uint32_t mailbox_number ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; volatile PSP_INTERRUPT_TABLE_INDEX index; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) { return (FLEXCAN_INVALID_MAILBOX); } /* Start CR# 1750 */ can_reg_ptr->IMASK &= ~(0x1 << mailbox_number); /* End CR# 1750 */ index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number); if (0 == index) { return (FLEXCAN_INT_DISABLE_FAILED); } /* Disable the interrupt */ if (_flexcan_int_init (index, FLEXCAN_MESSBUF_INT_LEVEL, FLEXCAN_MESSBUF_INT_SUBLEVEL, FALSE) != MQX_OK) { return (FLEXCAN_INT_DISABLE_FAILED); } return (FLEXCAN_OK); }
/*FUNCTION**************************************************************** * * Function Name : FLEXCAN_int_enable * Returned Value : uint32_t * Comments : * This function enables interrupt for requested mailbox * *END*********************************************************************/ uint32_t FLEXCAN_Int_enable ( /* [IN] FlexCAN device number */ uint8_t dev_num, /* [IN] mailbox number */ uint32_t mailbox_number ) { volatile FLEXCAN_REG_STRUCT_PTR can_reg_ptr; volatile PSP_INTERRUPT_TABLE_INDEX index; can_reg_ptr = _bsp_get_flexcan_base_address (dev_num); if (NULL == can_reg_ptr) { return (FLEXCAN_INVALID_ADDRESS); } if ( mailbox_number > (FLEXCAN_CANMCR_MAXMB (0xFFFFFFFF)) ) { return (FLEXCAN_INVALID_MAILBOX); } index = _bsp_get_flexcan_vector (dev_num, FLEXCAN_INT_BUF, mailbox_number); if (0 == index) { return (FLEXCAN_INT_ENABLE_FAILED); } if (_flexcan_int_init (index, FLEXCAN_MESSBUF_INT_LEVEL, FLEXCAN_MESSBUF_INT_SUBLEVEL, TRUE) != MQX_OK) { return (FLEXCAN_INT_ENABLE_FAILED); } /* IMASK, unmask the message buffer */ (can_reg_ptr->IMASK) |= (0x1 << mailbox_number); return( FLEXCAN_OK ); }