rtems_status_code mpc55xx_edma_obtain_channel( edma_channel_context *ctx, unsigned irq_priority ) { rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd); if (sc == RTEMS_SUCCESSFUL) { unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); sc = mpc55xx_interrupt_handler_install( MPC55XX_IRQ_EDMA(channel_index), "eDMA Channel", RTEMS_INTERRUPT_SHARED, irq_priority, edma_interrupt_handler, ctx ); if (sc == RTEMS_SUCCESSFUL) { rtems_chain_prepend(&edma_channel_chain, &ctx->node); mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd); } else { mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd); sc = RTEMS_IO_ERROR; } } return sc; }
void mpc55xx_edma_init(void) { rtems_status_code sc = RTEMS_SUCCESSFUL; unsigned channel_remaining = EDMA_CHANNEL_COUNT; unsigned module = 0; unsigned group = 0; for (module = 0; module < EDMA_MODULE_COUNT; ++module) { volatile struct EDMA_tag *edma = edma_get_regs_by_module(module); unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ? channel_remaining : EDMA_CHANNELS_PER_MODULE; unsigned channel = 0; channel_remaining -= channel_count; /* Disable requests */ edma->CERQR.B.CERQ = 0x40; /* Arbitration mode: group round robin, channel fixed */ edma->CR.B.ERGA = 1; edma->CR.B.ERCA = 0; for (channel = 0; channel < channel_count; ++channel) { volatile struct tcd_t *tcd = &edma->TCD [channel]; edma->CPR [channel].R = 0x80U | (channel & 0xfU); /* Initialize TCD, stop channel first */ tcd->BMF.R = 0; tcd->SADDR = 0; tcd->SDF.R = 0; tcd->NBYTES = 0; tcd->SLAST = 0; tcd->DADDR = 0; tcd->CDF.R = 0; tcd->DLAST_SGA = 0; } /* Clear interrupt requests */ edma->CIRQR.B.CINT = 0x40; edma->CER.B.CERR = 0x40; } for (group = 0; group < EDMA_GROUP_COUNT; ++group) { sc = mpc55xx_interrupt_handler_install( MPC55XX_IRQ_EDMA_ERROR(group), "eDMA Error", RTEMS_INTERRUPT_UNIQUE, MPC55XX_INTC_DEFAULT_PRIORITY, edma_interrupt_error_handler, NULL ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL); } } }
static void mpc55xx_clock_handler_install( rtems_isr_entry isr, rtems_isr_entry *old_isr) { rtems_status_code sc = RTEMS_SUCCESSFUL; sc = mpc55xx_interrupt_handler_install( MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL), "clock", RTEMS_INTERRUPT_UNIQUE, MPC55XX_INTC_MIN_PRIORITY, (rtems_interrupt_handler) isr, NULL ); *old_isr = NULL; RTEMS_CHECK_SC_VOID( sc, "install clock interrupt handler"); }
static void mpc55xx_clock_handler_install(rtems_isr_entry isr) { rtems_status_code sc = RTEMS_SUCCESSFUL; sc = mpc55xx_interrupt_handler_install( MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL), "clock", RTEMS_INTERRUPT_UNIQUE, MPC55XX_INTC_MIN_PRIORITY, (rtems_interrupt_handler) isr, NULL ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_IRQ_INSTALL); } }
static int mpc55xx_esci_set_attributes(int minor, const struct termios *t) { mpc55xx_esci_context *self = console_generic_get_context(minor); volatile struct ESCI_tag *regs = self->regs; union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS; rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_cflag); /* Enable module */ cr2.B.MDIS = 0; /* Interrupts */ cr1.B.TCIE = 0; cr1.B.ILIE = 0; cr2.B.IEBERR = 0; cr2.B.ORIE = 0; cr2.B.NFIE = 0; cr2.B.FEIE = 0; cr2.B.PFIE = 0; /* Disable receiver wake-up standby */ cr1.B.RWU = 0; /* Disable DMA channels */ cr2.B.RXDMA = 0; cr2.B.TXDMA = 0; /* Idle line type */ cr1.B.ILT = 0; /* Disable loops */ cr1.B.LOOPS = 0; /* Enable or disable receiver */ cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0; /* Enable transmitter */ cr1.B.TE = 1; /* Baud rate */ if (br > 0) { br = bsp_clock_speed / (16 * br); br = (br > 8191) ? 8191 : br; } else { br = 0; } cr1.B.SBR = br; /* Number of data bits */ if ((t->c_cflag & CSIZE) != CS8) { return -1; } cr1.B.M = 0; /* Parity */ cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0; cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0; /* Stop bits */ if (t->c_cflag & CSTOPB ) { /* Two stop bits */ return -1; } /* Disable LIN */ regs->LCR.R = 0; /* Set control registers */ regs->CR2.R = cr2.R; regs->CR1.R = cr1.R; return 0; } static int mpc55xx_esci_first_open(int major, int minor, void *arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; int rv = 0; mpc55xx_esci_context *self = console_generic_get_context(minor); struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg); self->tty = tty; rv = rtems_termios_set_initial_baud(tty, 115200); if (rv != 0) { rtems_fatal_error_occurred(0xdeadbeef); } rv = mpc55xx_esci_set_attributes(minor, &tty->termios); if (rv != 0) { rtems_fatal_error_occurred(0xdeadbeef); } sc = mpc55xx_interrupt_handler_install( self->irq, "eSCI", RTEMS_INTERRUPT_UNIQUE, MPC55XX_INTC_DEFAULT_PRIORITY, mpc55xx_esci_interrupt_handler, self ); if (sc != RTEMS_SUCCESSFUL) { rtems_fatal_error_occurred(0xdeadbeef); } mpc55xx_esci_interrupts_clear_and_enable(self); self->transmit_in_progress = false; return 0; }