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 Reply
  • Dan:

    Here's the link to the MCBSTR9 schematic (pdf form):

    http://www.keil.com/mcbstr9/mcbstr9-schematics.pdf

    As I understand it, you have to set up several registers in the assembly startup file. These seem to relate primarily to clock speeds, clock gating, power, and reset state.

    The setting up of the UART(s) can be done mostly in C code. This include the setting of the modes (parity, stop bits, etc.) as well as baud rate (integer divisor, fractional divisor), and enable/disable. This code is in my original post.

    The answer to your question regaring whether Keil supplied a serial comm example is not so straightforward. The two examples provided were BLINKY (excercises timer, LCD, ADC, and LEDS) and a webserver written by a third party (Easyweb is what I think it was called). These were located in a directory C:\Keil\ARM\RV30\Boards\Keil\MCBSTR9

    Keil also supplied a number of examples from ST (for example C:\Keil\ARM\RV30\Examples\ST\STR91xLib\UART\EXAMPLE1)

    It appears that this example is set up for some sort of demo board made by ST since it uses GPIO ports 5,3, and 2 for Rx, TX, RTS, and CTS respectively. Given the the MCBSTR9 board only uses pins from GPIO3 (TX and RX only), I didn't try to run the example on my Keil board.

    In the course of making a decision to go with the STR9, I asked Keil if they could send me one of the examples from the RTL kit (RTOS, TCP/IP, etc) so that I could get a feel for the level of effort required to use the TCP/IP stack. The example, LEDSwitch.C, sets up a client that switches an LED in response to TCP packets sent from a PC. Besides switching the LED, it sends a message out the serial port.

    Now, to the point...It is this piece of code that I modified to create the program I originally posted.

    But to answer your question directly: No Keil didn't provide a UART example. Nor do they seem inclined to do so. In several e-mail exchanges with Keil, their tech support guy said that he/they didn't have time to provide one and that if I or ST could tell them which registers to modify, he could tell me how to do that using the Keil tools. Apparently, Keil doesn't know which registers to set up to make a STR9 UART work either.

    On a positive note; I'm glad to see that you are going to be using STR9 as well. I was beginning to think I was the only one who was using the chip/board!

    Thanks Again,

    -=Rich=-

Children
More questions in this forum