Issue wih UART1 and SD card bootloader

Hi dear Keil fellows,

I am developping a SD card bootloader based on the app note AN10835: LPC2000 Secondary bootloader. I don't need the menu and the command set to match the requirements of my application, but I think that displaying messages on the UART is a good way to get an easy debug monitoring. To achieve this goal I use the retarget.c and serial.c files provided with the app note but I am not able to get any frame I am supposed to send on my terminal.

I made many in-depth searchs over the inernet and in the LPC23xx user manual without success. I've seen few errors in the init_serial function so I modified it to match NXP's instructions.

The original init_serial:

/*----------------------------------------------------------------------------
 *       init_serial:  Initialize Serial Interface
 *---------------------------------------------------------------------------*/
/* init UART1, 115200/8/N/1, suppose PCLK=12MHz,  */
void init_serial () {
   /* Initialize the serial interface */

   /* Configure UART1 for 115200 baud. */
   PINSEL0 &= ~0xC0000000;
   PINSEL0 |=  0x40000000;                   /* Enable TxD1 pin              */
   PINSEL1 &= ~0x00000003;
   PINSEL1 |=  0x00000001;                   /* Enable RxD1 pin              */

   U1LCR = 0x83;                             /* 8 bits, no Parity, 1 Stop bit*/
   U1DLL = 3;                                /* for 12MHz PCLK Clock         */
   U1FDR = 0x67;                             /* Fractional Divider           */
   U1LCR = 0x03;                            /* DLAB = 0                     */
}

The one I use now:

/*----------------------------------------------------------------------------
 *       init_serial:  Initialize Serial Interface
 *---------------------------------------------------------------------------*/
/* init UART1, 115200/8/N/1, suppose PCLK=12MHz,  */
void init_serial () {
   /* Initialize the serial interface */

   /* Configure UART1 for 115200 baud. */
   PINSEL0 &= ~0xC0000000;
   PINSEL0 |=  0x40000000;                   /* Enable TxD1 pin              */
   PINSEL1 &= ~0x00000003;
   PINSEL1 |=  0x00000001;                   /* Enable RxD1 pin              */

   U1LCR = 0x83;                             /* 8 bits, no Parity, 1 Stop bit*/
   U1DLL = 4;                                /* for 12MHz PCLK Clock         */
   U1FDR = 0x85;                             /* Fractional Divider           */
   U1LCR &= 0x7F;                            /* DLAB = 0                     */
}


NB: Those values are from LPC23xx user manual page 455.

I was suspecting an issue with the retargeting of printf so I made a little funcion I called uprintf to not call printf.

/*----------------------------------------------------------------------------
 *       uprintf:  Print a string on Serial Port
 *---------------------------------------------------------------------------*/
void uprintf ( const char *buf , char len )
{
        for(  ; len ; len--) sendchar (*buf++);
}

I use this function in combination with sprintf:

char len;
char buf[128];

len = sprintf(buf, "\n> Initializing SD/MMC Card : ");
uprintf(buf, len);

Even with this method I don't have anything on my terminal. I managed to monitor the TXD1 pin with an oscilloscope but the pin remains tied to high level so I ask to know if you guys have any idea of what is going on or what I am doing wrong ?

My target is a LPC2388 and I develop with µvision 4.02 and RL-ARM 3.4 if it can help.

Thanks in advance for your help :)

Kind regards.

Parents
  • Not sure how the SD card plays into the UART not working.

    Make sure you're clocking at 12 MHz, and not something else, otherwise all the math fails. The UART also uses CMOS levels, not RS232, so consider how it is wired. If you need to confirm the baud rate send a continuous stream (0x55, or 0xAA for example) and confirm the bit timings on a scope.

    // (((12000000 / 16) * 5) / 8) / 4 = 117187.5 (+1.7%)
    
      UxFDR    = 0x85;                       /* Fractional divider 5/8            */
      UxLCR    = 0x83;                       /* 8 bits, no Parity, 1 Stop bit     */
      UxDLL    = 4;                          /* 115200 Baud Rate @ 12.0 MHZ PCLK  */
      UxDLM    = 0;                          /* High divisor latch = 0            */
      UxLCR    = 0x03;                       /* DLAB = 0                          */
    

    You could also use the fact that C strings are NUL terminated

    void uputs ( const char *buf)
    {
      while(*buf) sendchar (*buf++);
    }
    

Reply
  • Not sure how the SD card plays into the UART not working.

    Make sure you're clocking at 12 MHz, and not something else, otherwise all the math fails. The UART also uses CMOS levels, not RS232, so consider how it is wired. If you need to confirm the baud rate send a continuous stream (0x55, or 0xAA for example) and confirm the bit timings on a scope.

    // (((12000000 / 16) * 5) / 8) / 4 = 117187.5 (+1.7%)
    
      UxFDR    = 0x85;                       /* Fractional divider 5/8            */
      UxLCR    = 0x83;                       /* 8 bits, no Parity, 1 Stop bit     */
      UxDLL    = 4;                          /* 115200 Baud Rate @ 12.0 MHZ PCLK  */
      UxDLM    = 0;                          /* High divisor latch = 0            */
      UxLCR    = 0x03;                       /* DLAB = 0                          */
    

    You could also use the fact that C strings are NUL terminated

    void uputs ( const char *buf)
    {
      while(*buf) sendchar (*buf++);
    }
    

Children
More questions in this forum