This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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
  • Hello Pier,

    Thank you for your answer.

    First of all, I am 100% sure that I run at PCLK = 12MHz. My problem isn't the baudrate, I just can't get anyhing out of my UART.

    I think this is a retargeting issue, but I don't understand how and why, I am not used to this technique. I am using serial.c and retarget.c files which are supposed to work well "out of the box" and I don't know why it is not the case.

    Regards.

  • Then ignore all the retargeting clutter and focus on a simple demo where you enable the UART in main() and send a stream of characters in a loop. There is no point proceeding until you can get that working.

    Is this on some regular eval board, or a custom board? Provide some more details. Check the UART and pin assignments.