voidinit(void){  // Set up an interrupt handler for DMA0 mcf5282_interrupt_init(9,         MCF5282_INTC_ICR_IL(5)         | MCF5282_INTC_ICR_IP(3),         data_pump_isr);  // Clear DMA0 MCF5282_DMA0_DSR = MCF5282_DMA_DSR_DONE; }/**************************************************************************** * FUNCTION: start_copy_isr(void) *  * ISR servicing an external interrupt which starts the DMA data pump *  * RETURNS:  nothing *  * When the interrupt is asserted, the peripheral has one or more buffers full of * data. This ISR will start a DMA transfer for the first full buffer. The * DMA completion interrupt will start another DMA transfer if there is any * more data left to transfer. *  */__attribute__((interrupt_handler)) voidstart_copy_isr(){ // Some code removed here that just works out which // buffer to use as a destination - we have a double // buffering scheme in use here. SRC_BUFFER_BA(chnl) is // the address of the correct source buffer. // DST_BUFFER_BA(chnl) is the base address of the destination. // BUF_LEN is the buffer length. We make sure our // buffers are on 16-byte aligned addresses so that // we can fource line xfers.      // Configure a DMA transfer to current_buffer MCF5282_DMA0_SAR = (uint32)SRC_BUFFER_BA(chnl); MCF5282_DMA0_DAR = (uint32)DST_BUFFER_BA(chnl); MCF5282_DMA0_BCR = BUF_LEN << 16;  MCF5282_DMA0_DCR = 0 | MCF5282_DMA_DCR_INT    // Enable DMA interrupt       | MCF5282_DMA_DCR_SINC    // Inc src addr       | MCF5282_DMA_DCR_DINC    // Inc dst addr       | MCF5282_DMA_DCR_SSIZE_LINE  // 16 byte src xfer       | MCF5282_DMA_DCR_DSIZE_LINE;  // 16 byte dst xfer        MCF5282_DMA0_DCR |= MCF5282_DMA_DCR_START;    // Start DMA xfer // A bit more housekeeping deleted here. Mainly to mask the // external peripheral's interrupt. The DMA completion ISR will // check if the peripheral still has more data to transfer.}/**************************************************************************** * FUNCTION: data_pump_isr(void) *  * ISR for the data pump interrupt on DMA completion *  * RETURNS:  nothing *  * When a DMA transfer completes, this handler will be called. The source peripheral * status is examined and if another buffer is ready to go, then another * DMA transfer is initiated. If there is no more data, we reset our * state to wait for another buffer full of data. *  */__attribute__((interrupt_handler)) voiddata_pump_isr(void){ // Write DMA0(DONE) = 1 to clear interrupt MCF5282_DMA0_DSR = MCF5282_DMA_DSR_DONE; // The DMA transfer for the current buffer has completed. // Code removed here that will deal with the now filled // target buffer.  // Check if any other buffers need to be serviced if (SRC_BUF_FULL(chnl)) {   // Configure a DMA transfer to the relevant buffer   MCF5282_DMA0_SAR = (uint32)SRC_BUFFER_BA(chnl);   MCF5282_DMA0_DAR = (uint32)TGT_BUFFER_BA(chnl);   MCF5282_DMA0_BCR = BUF_LEN << 16;   MCF5282_DMA0_DCR = 0 | MCF5282_DMA_DCR_INT         | MCF5282_DMA_DCR_SINC         | MCF5282_DMA_DCR_DINC         | MCF5282_DMA_DCR_SSIZE_LINE         | MCF5282_DMA_DCR_DSIZE_LINE         | MCF5282_DMA_DCR_START;            // New DMA transfer is now started } else {  // No more data so put the peripheral in a state so that it  // can trigger a new transfer }}/* FUNCTION: mcf5282_interrupt_init() * * Initialise an interrupt handler for an interrupt source * for INTC0. If the handler is a NULL pointer, then mask * this interrupt. * * PARAM1: Interrupt source (1..62) * * PARAM2: Interrupt level and priority * * PARAM3: Interrupt handler * * RETURNS: none */voidmcf5282_interrupt_init(uint8 source, uint8 ipl, void (*handler)(void)){ // Only for user defined vectors in INTC0 if ((source > 0) && (source < 63)) {  // Interrupts should be disabled to avoid vector problems  // and to ensure that a spurious interrupt exception can't  // be generated.  uint8 sysint = asm_set_ipl(7);  if (handler)  {   // Set interrupt priority level   MCF5282_INTC0_ICR(source) = (ipl & 0x3F);   // Set vector   mcf5xxx_set_handler(source+64, (ADDRESS)handler);   // Clear mask for this handler   if (source < 32)    MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT(source)          | MCF5282_INTC_IMRL_MASKALL);   else   {    MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_MASKALL);    MCF5282_INTC0_IMRH &= ~(MCF5282_INTC_IMRH_INT(source));   }  }  else  {   // Set vector   mcf5xxx_set_handler(source+64, (ADDRESS)handler);   // Set mask for this handler   if (source < 32)   {    MCF5282_INTC0_IMRL |= MCF5282_INTC_IMRL_INT(source);   }   else   {    MCF5282_INTC0_IMRH |= MCF5282_INTC_IMRH_INT(source);   }  }  // As you were...  asm_set_ipl(sysint); }}OK, Paul. In the following lines you'll see the init procedure for the bridge (bridge_init), the init procedure for DMA (dma_uart_init), the Interrupt Enable procedure (EnableDMAinInterrupt) and the interrupt routine.
char bridge_init(unsigned char ucBridge, unsigned long int ulBaud_rateUART0, unsigned long int ulBaud_rateUART1){
  struct uartbridge_desc* uartbridge; 
  // initialize structure
 [...]
  // initialize buffers
 [...]
 // initialize pointers
  [...]
 // initialize UART0
 uartbridge->ucDevice_UART0=0;
 if (uart_init(uartbridge->ucDevice_UART0, ulBaud_rateUART0) != -1){
   uartbridge->ulSpeed_UART0=ulBaud_rateUART0;
    uartbridge->vucUART0_idle=1; 
  uartbridge->ucInitdone_UART0=1;
  printf("UART0 initialized\n\r");
 }
  
 // initialize UART1
 uartbridge->ucDevice_UART1=1;
 if (uart_init(uartbridge->ucDevice_UART1, ulBaud_rateUART1) != -1){
   uartbridge->ulSpeed_UART1=ulBaud_rateUART1;
  uartbridge->ucInitdone_UART1=1;
  printf("UART1 initialized\n\r");
 }
  
 // UART1 DMA1
 uartbridge->ucUART1_DMA_in=1;         // initialize input DMA ch1
 dma_uart_init(uartbridge->ucDevice_UART1, uartbridge->ucUART1_DMA_in, uartbridge->ucpUART1_RXBuf);
 EnableDMAinInterrupt(ucBridge,UART1_DMA_ch);         // unmask DMA1 interrupt
 MCF_UART_UCR(uartbridge->ucDevice_UART1)=MCF_UART_UCR_RESET_MR;   // reset UMR
 MCF_UART_UMR(uartbridge->ucDevice_UART1) = (   MCF_UART_UMR_PM_NONE  // no parity
                 | MCF_UART_UMR_SB(0x07)  // stop bit
                 | MCF_UART_UMR_CM_NORMAL // no loopback
                 | MCF_UART_UMR_BC(0x03)); // 8 bit
// UART0 DMA0
 uartbridge->uc_UART0_in=0;         // initialize input DMA ch0
 dma_uart_init(uartbridge->ucDevice_UART0, uartbridge->ucUART0_DMA_in, uartbridge->ucpUART0_RXBuf);
 EnableDMAinInterrupt(ucBridge, UART0_DMA_ch);        // unmask DMA0 interrupt
 
 MCF_UART_UCR(uartbridge->ucDevice_UART0)=MCF_UART_UCR_RESET_MR;   // reset UMR
 MCF_UART_UMR(uartbridge->ucDevice_UART0) = ( MCF_UART_UMR_PM_NONE  // no parity
                 | MCF_UART_UMR_SB(0x07)  // stop bit
                 | MCF_UART_UMR_CM_NORMAL // no loopback
                 | MCF_UART_UMR_BC(0x03)); // 8 bit
   return 0;
  
 }
char dma_uart_init(unsigned char ucDev, unsigned char ucChan, unsigned char* ucpBuffer){
  
 // route DMA channel 1 to UART1 module
 if ((ucDev==1) && (ucChan==1)){
  MCF_DMA_DMAREQC |= MCF_DMA_DMAREQC_DMAC1(0x9);   //route DMA Ch1 to UART1 RX
  MCF_DMA_SAR1=(volatile unsigned long)&MCF_UART1_URB; //DMA Ch1 source address
  MCF_DMA_DAR1=(volatile unsigned long) ucpBuffer;  //DMA Ch1 dest address
  MCF_DMA_BCR1=MCF_DMA_BCR_BCR(BLOCKSIZE);    //byte number
  
  MCF_DMA_DCR1 |= MCF_DMA_DCR_INT |    //enable int
            MCF_DMA_DCR_EEXT |                         //enable external request
            MCF_DMA_DCR_CS |                             //forces a single r/w cycle per request
            MCF_DMA_DCR_SSIZE(0x1) |                //1 byte size for source bus cycle
            MCF_DMA_DCR_DINC |                          //enable dest increment
            MCF_DMA_DCR_DSIZE(0x1);                //1 byte size for dest bus cycle
 
  MCF_SCM_RAMBAR |= MCF_SCM_RAMBAR_BDE;   //enable access to SRAM
  MCF_SCM_PACR2 |= MCF_SCM_PACR_UART1_RW;   //give r/w access to user/superuser
  printf("DMA1 initialized \n\r");
  return 0;
  }
 
 // route DMA channel 0 to UART0 module
 if ((ucDev==0) && (ucChan==0)){
  MCF_DMA_DMAREQC |= MCF_DMA_DMAREQC_DMAC0(0x8);   //route DMA Ch0 to UART0 RX
  MCF_DMA_SAR0=(volatile unsigned long)&MCF_UART0_URB; //DMA Ch0 source address
  MCF_DMA_DAR0=(volatile unsigned long) ucpBuffer;  //DMA Ch0 dest address
  MCF_DMA_BCR0=MCF_DMA_BCR_BCR(BLOCKSIZE);    //byte number
  
  MCF_DMA_DCR0 |= MCF_DMA_DCR_INT |  //enable int
        MCF_DMA_DCR_EEXT |                           //enable external request
        MCF_DMA_DCR_CS |                               //forces a single r/w cycle per request
        MCF_DMA_DCR_SSIZE(0x1) |                  //1 byte size for source bus cycle
        MCF_DMA_DCR_DINC |                            //enable dest increment
        MCF_DMA_DCR_DSIZE(0x1);                   //1 byte size for dest bus cycle
 
  MCF_SCM_RAMBAR |= MCF_SCM_RAMBAR_BDE;   //enable access to SRAM
  MCF_SCM_PACR2 |= ((MCF_SCM_PACR_UART0_RW)<<4); //give r/w access to user/superuser
  printf("DMA0 initialized \n\r");
  return 0;
  }
 
 return -1; 
}
 void EnableDMAinInterrupt(unsigned char ucBridge, unsigned char ucDMA_number){
  struct uartbridge_desc* uartbridge=&uartbridges[ucBridge];
  
  if (ucDMA_number==1){     //DMA1 for UART1
        MCF_INTC0_ICR10= DMA1_Int_setting;
        MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK10 | MCF_INTC_IMRL_MASKALL);
  }
  
  else if (ucDMA_number==0){   //DMA0 for UART0
        MCF_INTC0_ICR9= DMA0_Int_setting;
        MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK9 | MCF_INTC_IMRL_MASKALL);
  }
  
 else {
  printf("Enable DMA in int operation failed!");
 }
 }
The interrupt routine for DMA1 is:
__declspec(interrupt) void dma1_isr (void){
   unsigned char ucUART_usr,ucDMA_usr,ucUART1Buf_next;
   signed char scRoom;
   struct uartbridge_desc* uartbridge;
   unsigned char ucDevin;
   unsigned char ucDMA_in;
   int i;
 
   ulUART1_Int_DMAin_hit++;
   ucDevin=1;
   ucDMA_in=1;
  ucUART_usr=MCF_UART_USR(ucDevin);     //read input UART status
  MCF_UART_UCR(ucDevin)=MCF_UART_UCR_RESET_ERROR;  //reset input UART error status
  ucDMA_usr=MCF_DMA_DSR(ucDMA_in);     //read DMA status
   if (ucDMA_usr & MCF_DMA_DSR_DONE){   //check the interrupt source
     ulUART1_Int_DMAin_done_hit++;
   
    // input UART error check
    if (ucUART_usr & (MCF_UART_USR_OE |  //overrun error
             MCF_UART_USR_PE |  //parity error
             MCF_UART_USR_FE |  //framing error
             MCF_UART_USR_RB )) //received break
     { 
       printf("Input UART1 error.");
       ulUART1_in_err_counter++;
    }
    // input DMA error check
    if (ucDMA_usr & (MCF_DMA_DSR_CE | //configuration error
             MCF_DMA_DSR_BES | //source error
            MCF_DMA_DSR_BED | //dest error
            MCF_DMA_DSR_REQ //pending req
          )){
      printf("Input DMA1 error.");
      ulUART1_DMAin_err_counter++;
     
     MCF_DMA_DSR(ucDMA_in) |= MCF_DMA_DSR_DONE;
     MCF_DMA_DMAREQC=0;  //remove routing between UART and DMA
    }
    else {
   if ((ucUART1Buf_next=uartbridge->vucUART1Buf_in+BLOCKSIZE)>=UARTRTXBUFSIZE)
      ucUART1Buf_next-=UARTRTXBUFSIZE;
  
     // RX buf full check
     scRoom=(uartbridge->vucUART1Buf_out - ucUART1Buf_next);  //room left
   if (scRoom < 0) scRoom+=UARTRTXBUFSIZE;  
     if (scRoom < BLOCKSIZE) ulUART1_DMAbytein_drop++;  //no room left: drop one frame, don't update
      else {
      uartbridge->vucUART1Buf_in=ucUART1Buf_next;      //there is room left: update vucRx_in
      uartbridge->vucUART1_idle=0;
   }
      
      MCF_DMA_DAR(ucDMA_in)=(volatile unsigned long) (uartbridge->ucpUART1_RXBuf + uartbridge->vucUART1Buf_in); //update the DMA pointer
     
     MCF_DMA_DMAREQC=0;        //stop routing DMA channel to UART
     MCF_DMA_DSR(ucDMA_in) |= MCF_DMA_DSR_DONE;  //clear DMA interrupt and error bits 
       MCF_DMA_BCR(ucDMA_in) |= MCF_DMA_BCR_BCR(BLOCKSIZE);
      MCF_DMA_DMAREQC |= MCF_DMA_DMAREQC_DMAC1(0x9); //restore routing DMA channel to UART
     }
   }
    else ulUART1_Int_DMAin_diff_hit++;
 }
 
The routine for DMA0 is dual. In the file mcf52235_vectors.s I modified the following:
//vector49: .long _irq_handler
vector49: .long _dma0_isr /* DMA0 ISR */
//vector4A: .long _irq_handler
vector4A: .long _dma1_isr /* DMA1 ISR */
vector4B: .long _irq_handler
Please, try to give me some hint.
Thank you in advance.
Kremer wrote:I just didn´t understand why you did this:MCF5282_DMA0_BCR = BUF_LEN << 16;
MCF5223x_DMA0_BCR = BUF_LEN;
