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

UART on ARM9

Gentlemen(Ladies):

I've been wrestling with trying to get output from one of the two UARTs on my Keil MCBSTR9 board (vers 3). All to no avail. I've checked baudrates and the setup of the UART and the System Control Unit. Part of the attached code works (LCD output, LED output) so I know that at least the processor is coming out of reset and is running some code. Trouble is, when I try to send a character out the port, the code hangs. If I comment out the two calls to sendchar(), the remaining code runs fine.

I've posted my code below (with comments explaining what I was attempting to do. If it is simple enough to identify what I'm doing wrong, I would greatly appreciate being educated.

Or, if deciphering my bad code is beyond the wit/patience of man, then I would appreciate a sample of any serial port code that DOES run on the MCBSTR9 board.

I apologize in advance for the appearance of the code after I copied it from the IDE to the form posting editor. I tried my best to clean it up, but I'm not at all happy with how it renders (at least on my browser). Any suggestions on how to fix that problem would be duly noted and taken on board.

//*************************** TEST.C ************************************
// Auth: R. McCoy
// Date: 9/30/2006
// Gist: Blinks LEDS on port 7 of Keil MCBSTR9 board. Also TRYING to spit a
//                character ('A') out of COM1 (UART0).
// Note: It appears that there is an error in the documentation on page 78 of
//                ST Manual UM0216 (STR91x Reference manual). The SCU_GPOINn register
//                documentation makes no sense whatsoever. Only 8 bits are shown...not
//                the 16 bits that should be depicted. Also, why does the table jump from
//                pin3 to pin7 (going right to left)?
// Stat: No luck so far.
//
// Targ: Using the Keil MCBSTR9 Demo Board:
//           COM1 is connected to pins P3.0 (Rx) and P3.1 (TX)
//       COM2 is connected to pins P3.2 (Rx) and P3.3 (TX)
//
//       Per Table 4 of the Str91xF (ARM966E-S) datasheet (STR912FW44.pdf):
//       UART0 Rx is Alt Input 1 on GPIO_3.0
//       UART0 Tx is Alt Output 2 on GPIO_3.1
//
//       Board is operating at 48 Mhz and the BRDi and BRDf registers
//               are set up to generate a baudrate of 115,200.
//***********************************************************************

#include <91x_lib.h>
#include "LCD.h"
int sendchar(int ch);
int retval;


int main (void) {
  unsigned int i;
  SCU->GPIOOUT[7]  = 0x5555;    /* P7.0..7 output - mode 1          */
  GPIO7->DDR       = 0xFF;      /* P7.0..7 Outputs (LED Data)       */

  /* LCD Setup......................................................*/
  GPIO8->DDR       = 0xFF;      /* P8.0..7 Outputs (LCD Data)       */
  GPIO9->DDR       = 0x07;      /* P9.0..2 Outputs (LCD Control)    */

 /* UART1 Setup.....................................................*/

   SCU->GPIOOUT[3] &= 0xFF3F;   /* Enable UART0_TX (COM1) connected to P3.1  */
                                /* by setting bits 6 & 7 to 0 first */
   SCU->GPIOOUT[3] |= 0x0080;   /* then by setting bit 7 to 1  */
                                                                /* this sets GPIOOUT[3] to "Alternate Output 2" */

   SCU->GPIOIN[3]  |= 0x01;          /* Enable UART0_RX (COM1) connected to P3.0             */
                                                                /* by setting bit 0 to 1                                */
                                                                /* this sets GPIOIN[3] to "Alternate Input 1" */

   UART0->IBRD = 0x1A;          /* Integer divider for 115kBaud */
   UART0->FBRD = 0x03;          /* Fractional divider           */
   UART0->LCR  = 0x0060;        /* 8 bits, no Parity, 1 Stop bit, FIFO disabled */
   UART0->CR   = 0x0301;        /* Enable UART, Receive Enable, Transmit Enable */

  lcd_init();
  lcd_clear();
  lcd_print (" TEST.C  ");      /* this line of code works */
  set_cursor (0, 1);
  lcd_print ("  Sept. 30, 2006  ");  /* this line of code works */
  /* retval=sendchar('A');       if this line is left un-commented, the code      */
                                                                         /* compiles and loads, but the program hangs */

  for (i = 0; i < 5; i++) wait();    /* Wait for initial display         */
  while (1) {                        /* Loop forever                     */
      int n=0;
      for(n=0x01;n<=0xFF;n<<=1)             /* scroll thru all eight LEDS                */
          {
          GPIO7->DR[0x3FC] = n;          /* Turn on LED ...this code works   */
      wait();                        /* Delay                            */
          /* retval=sendchar('A');               if this line is left un-commented, the code      */
                                                                         /* compiles and loads, but the program hangs */
      }
  }
}

int sendchar (int ch)  {
   /* Debug output to serial port. */

   if (ch == '\n')  {
      while (!(UART1->FR & 0x0080));
      UART0->DR = '\r';               /* output CR    */
   }
   while (!(UART1->FR & 0x0080));
   return (UART0->DR = ch);
}

void wait (void)  {          /* Wait function                    */
  long d=950000L;                        /* 950,000 gives a delay of about 1 sec. */
  while (d--);               /* Only to delay for LED flashes    */
}

Thanks in Advance, -=Rich=-

Parents
  • Dan:

    I have a sneaking suspicion that you're right! I'm looking at the ST document 12274.pdf on page 39 and it looks like I definitely need to set P3.1 to "Alternate Output 2". That said, page 78 in ST document 112126.pdf says to set bits 3:2 to 1 and 0 respectively (0x08). I'll check it out tonight and revert in the A.M.

    Thanks so much!

    -=Rich=-

Reply
  • Dan:

    I have a sneaking suspicion that you're right! I'm looking at the ST document 12274.pdf on page 39 and it looks like I definitely need to set P3.1 to "Alternate Output 2". That said, page 78 in ST document 112126.pdf says to set bits 3:2 to 1 and 0 respectively (0x08). I'll check it out tonight and revert in the A.M.

    Thanks so much!

    -=Rich=-

Children
  • All:

    Dan made the call when he spotted that I had transposed nibbles. After making the suggested correction the code ran just fine.

    The following is the working code (for the benefit of anyone else that was having similar problems)

    
    //*************************** TEST.C ************************************
    // Auth:    R. McCoy
    // Date:    10/5/2006
    // Gist:    Blinks LEDS on port 7 of Keil MCBSTR9 board. Also spits a
    //          character ('A') out of COM1 (UART0).
    // Note:    It appears that there is an error in the documentation on page 78 of
    //                  ST Manual UM0216 (STR91x Reference manual). The SCU_GPOINn register
    //                  documentation makes no sense whatsoever. Only 8 bits are shown...not
    //          the 16 bits that should be depicted. Also, why does the table jump from
    //          pin3 to pin7 (going right to left)?
    // Stat:    Works fine.
    //
    // Targ:    Using the Keil MCBSTR9 Demo Board:
    //          COM1 is connected to pins P3.0 (Rx) and P3.1 (TX)
    //          COM2 is connected to pins P3.2 (Rx) and P3.3 (TX)
    //          Both ports are set up as DCE. This means you DON'T need a Null Modem
    //          cable. A DB-9 straight-thru works just fine.
    //
    //          Per Table 4 of the Str91xF (ARM966E-S) datasheet (STR912FW44.pdf):
    //          UART0 Rx is Alt Input 1 on GPIO_3.0
    //          UART0 Tx is Alt Output 2 on GPIO_3.1
    //
    //          Board is operating at 48 Mhz and the BRDi and BRDf registers
    //          are set up to generate a baudrate of 115,200.
    //
    //  Warn:   This file does not contain "production" code. It is written for
    //          testing purposes only. AS A RESULT, NEITHER RICHARD MCCOY NOR HIS EMPLOYER
    //          SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES
    //          WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE AND/OR
    //          THE USE MADE BY OTHERS OF THE CODING INFORMATION CONTAINED HEREIN IN
    //          CONNECTION WITH THEIR PRODUCTS.
    //***********************************************************************
    
    #include <91x_lib.h>
    #include "LCD.h"
    int sendchar(int ch);
    int retval;
    
    void wait (void){   /* Wait function                    */
      long d=950000L;   /* 950,000 gives a delay of about 1 sec. */
      while (d--);      /* Only to delay for LED flashes    */
    }
    int main (void) {
      unsigned int i;
      SCU->GPIOOUT[7]  = 0x5555;    /* P7.0..7 output - mode 1          */
      GPIO7->DDR       = 0xFF;      /* P7.0..7 Outputs (LED Data)       */
    
      /* LCD Setup......................................................*/
      GPIO8->DDR       = 0xFF;      /* P8.0..7 Outputs (LCD Data)       */
      GPIO9->DDR       = 0x07;      /* P9.0..2 Outputs (LCD Control)    */
    
     /* UART0 Setup.....................................................*/
    
       SCU->GPIOOUT[3] &= 0xFFF3;   /* Enable UART0_TX (COM1) connected to P3.1  */
                                    /* by setting bits 3 & 2 to 0 first */
       SCU->GPIOOUT[3] |= 0x0008;   /* then by setting bit 3 to 1  */
                                                                    /* this sets GPIOOUT[3] to "Alternate Output 2" */
                                    /* see page 78 of ST Microelectronics Document */
                                    /* UM0216 (12126.pdf) for info on this register */
                                    /* see page 39 of ST Microelectronics 12274.pdf- */
                                    /* STR91xF Data Sheet for information on alternate */
                                    /* pin functions */
    
       SCU->GPIOIN[3]  |= 0x01;          /* Enable UART0_RX (COM1) connected to P3.0             */
                                                                    /* by setting bit 0 to 1                                */
                                                                    /* this sets GPIOIN[3] to "Alternate Input 1" */
    
                                    /* Baud rate integer and fractional divisors were */
                                    /* calculated based on the Baud Rate Clock being */
                                    /* set to fMSTR (as opposed to fMSTR/2).         */
    
       UART0->IBRD = 0x1A;          /* Integer divider for 115kBaud */
       UART0->FBRD = 0x03;          /* Fractional divider           */
       UART0->LCR  = 0x0060;        /* 8 bits, no Parity, 1 Stop bit, FIFO disabled */
       UART0->CR   = 0x0301;        /* Enable UART, Receive Enable, Transmit Enable */
    
      lcd_init();
      lcd_clear();
      lcd_print (" TEST.C  ");      /* this line of code works as expected */
      set_cursor (0, 1);
      lcd_print ("  October 5, 2006  "); /* this line of code works as expected*/
      retval=sendchar('A');             /* This function returns */
    
      for (i = 0; i < 5; i++) wait();    /* Wait for initial display         */
      while (1) {                        /* Loop forever                     */
          int n=0;
          for(n=0x01;n<=0xFF;n<<=1)             /* scroll thru all eight LEDS                */
              {
              GPIO7->DR[0x3FC] = n;          /* Turn on LED ...this code works   */
          wait();                        /* Delay                            */
              retval=sendchar('A');              /* This function returns */
          }
      }
    }
    
    int sendchar (int ch)  {
       /* Debug output to serial port. */
    
       if (ch == '\n')  {
          while (!(UART0->FR & 0x0080));
          UART0->DR = '\r';
       }
       while (!(UART0->FR & 0x0080));
       return(UART0->DR = ch);
    
    
    }
    
    
    

    I should add that it took some time to figure out that several registers must be modified in the ST91x.s startup file. In particular were the: 1.) Clock control register (SCU_CLKCNTR) 2.) Peripheral Gate Control register (SCU_PCGR1) 3.) Peripheral Reset register (SCU_PRR1) If you don't have these set correctly, the UART won't work. I strongly suggest using the "Configuration Wizard" to modify your startup file. But, by all means, read the docs as well. Good Luck to all and a special thanks to Dan Henry. He's the one responsible for my still having some hair left! -=Rich=-

  • That's great news Rich! Thanks for closing the loop and for the acknowledgement.