In the Freescale examples (AN4830) all IRQs have default handlers for projects, demonstrating IRQ usage. I guess that xinweichang missed INTC initialization or something else. Enabling of IRQ through LINFlex configuration is not sufficient to get interrupt working. In addition, I don't see in the message above which core is in use. If core used is not Core0, then interrupt handling should be also directed to the right core...
I'm attaching one example (based on Freescale example, published some time ago). This one uses PIT interrupt, so controller is configured to handle IRQs properly.
xinweichang, code below configures LINFlex to use interrupts. It is directly taken from the OS driver I wrote, but you'll get the idea:
static void mpc57xx_linflex_init(SerialDriver *sdp, const SerialConfig *config) {
uint32_t div;
volatile struct LINFlexD_tag *linflexp = sdp->linflexp;
sdp->errNoise = sdp->errParity = sdp->errOverRun = sdp->errFraming = sdp->errBreak = 0;
/* Enters the configuration mode.*/
linflexp->LINCR1.B.INIT = 1; /* Put LIN in INIT mode */
linflexp->LINCR1.B.SLEEP = 0; /* No sleep */
/* Configures the LINFlex in UART mode with all the required parameters.*/
linflexp->UARTCR.B.UART = 1; /* Switch first to UART */
linflexp->UARTCR.R = MPC57XX_UARTCR_UART | MPC57XX_UARTCR_RXEN | MPC57XX_UARTCR_RFBM | config->mode;
div = sdp->clock / config->speed;
linflexp->LINIBRR.R = (uint16_t)(div >> 4); /* Integer divider. */
linflexp->LINFBRR.R = (uint16_t)(div & 15); /* Fractional divider. */
linflexp->UARTSR.R = 0xFFFF; /* Clearing UARTSR register.*/
linflexp->LINIER.R = MPC57XX_LINIER_DTIE | MPC57XX_LINIER_DRIE |
MPC57XX_LINIER_BOIE | MPC57XX_LINIER_FEIE |
MPC57XX_LINIER_SZIE; /* Interrupts enabled. */
/* Leaves the configuration mode.*/
linflexp->LINCR1.R = 0; /* Put LIN in NORM mode */
}
This is the receive interrupt routine:
static void mpc57xxxx_serve_rxi_interrupt(SerialDriver *sdp) {
flagsmask_t sts = 0;
uint16_t sr = sdp->linflexp->UARTSR.R;
sdp->linflexp->UARTSR.R = MPC57XX_UARTSR_NF | MPC57XX_UARTSR_DRF |
MPC57XX_UARTSR_PE0;
if (sr & MPC57XX_UARTSR_NF) {
sts |= SD_NOISE_ERROR;
sdp->errNoise++;
}
if (sr & MPC57XX_UARTSR_PE0) {
sts |= SD_PARITY_ERROR;
sdp->errParity++;
}
DISABLE_INTERRUPTS();
if (sts)
chnAddFlagsI(sdp, sts);
if (sr & MPC57XX_UARTSR_DRF) {
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA4);
sdp->linflexp->UARTSR.R = MPC57XX_UARTSR_RMB;
}
ENABLE_INTERRUPTS();
}
This is the transmit interrupt routine:
static void mpc57xxxx_serve_txi_interrupt(SerialDriver *sdp) {
msg_t b;
sdp->linflexp->UARTSR.R = MPC57XX_UARTSR_DTF;
DISABLE_INTERRUPTS();
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
sdp->linflexp->UARTCR.B.TxEn = 0;
} else {
sdp->linflexp->BDRL.B.DATA0 = b;
}
ENABLE_INTERRUPTS();
}
Don't forget that you have to handle error interrupt as well. In addition to all initialization done here, you have to set IRQ priority for the core which will handle the IRQ like this:
INTC.
INTC.PSR[vector].B.PRC_SELN<core> = 1;
INTC.PSR[vector].B.PRIN = <priority>;
Good luck!