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

Programming UART0/1 on uPSD3354

I cannot seem to get anything out of UART0 or 1 using printf(). What is the correct way to program these UARTS?

Thank you,
Stephen Blair

  • What is the correct way to program these UARTS?

    about 47 different ways

    show your attempt and guidance will appear

    Erik

  • I've got the uPSD3354 clocked by a TTL/CMOS powered 40MHz oscillator. In PSDsoft, I've got P1.3 set to TXD1 and P1.2 as RXD1. I've got P3.1 set to TXD0 and P3.0 as RXD0, with TXD0 going to a MAX232 to pin 11 and RXD0 going to pin 12. TXD0 out of the MAX goes to pin 2 while RXD0 in goes to pin 4.

    TXD1 and RXD1 are not wired out yet because I'm going to wire them to a serial Caller ID chip and haven't figured out if I need to invert any of these signals.

    I zipped up the code I'm using but don't know how to get it to you.

    Sincerely,
    Stephen Blair

  • a MAX232 to pin 11 and RXD0 going to pin 12. TXD0 out of the MAX goes to pin 2 while RXD0 in goes to pin 4.
    pin numbrs are meaningless, they vary from package to package e.g. PQFP and DIL, use pin names.

    I zipped up the code I'm using but don't know how to get it to you.
    just post the interesting parts here NOTE: no tabs, only spaces and bracketed with 'pre' as seen in the yellow above.

    Erik

  • The hardware side is fine. I assume this because I am getting a constant stream of spaces through COM1.

    Here's the relevent code:

    /*
            Main.c
            v1.0
            27 April 2008
    
            Copyright 04/27/08, Stephen J. Blair
    
            Contains the main loop for the entire program
    
    */
    #include "upsd3300.h"
    #include "upsd3300_hardware.h"
    #include "stdio.h"
    #include <main.h>
    #include <upsd_SIO.h>
    
    xdata volatile PSD_REGS PSD_reg _at_ PSD_REG_ADDR;       // Access PSD regs at CSIOP addr
    
    main()
    {
            unsigned int count;
    
            InitIOpins();
    
            com_initialize();                                       // initialize RS232 port
            TI = 1 ;
    
            count = 0;
    
            printf("\n\n");
    
            printf("printf on uPSD UART0\n\n");
    
            printf("Hello World\n");
    
            while(1)
            {
               printf("Count = %x\n", count);
           count++;
        }
    }
    
    void InitIOpins(void)
    {
            PSD_reg.PMMR0|=0x08;    // Disable PSD Module Turbo Mode to save power
            PSD_reg.PMMR2|=0x3C;    // Set PSD Module PLD input blocking bits to save power
                                                            // Block WR*, RD*, PSEN*, and ALE
    
            P1SFS0 = 0x0E;                  // Enable UART1 RX, TX on PORT 1
            P1SFS1 = 0x00;                  // Don't enable any ADC's PORT 1
    
            P3SFS  = 0x07;                  // Enable UART0 TX, RX, and EXTINT1 PORT 3
    
            P4SFS0 = 0x00;                  // Enable nothing on PORT 4
            P4SFS1 = 0x00;                  // Enable nothing on PORT 4
    
            PSD_reg.DIRECTION_A = 0xD9;     // set port pins PA0, PA3, PA4, PA6, PA7 (11011001) as outputs
            PSD_reg.OUTENABLE_A = 0xD9; // enable port pins as outputs if bit = 1
            PSD_reg.CONTROL_A = 0x00;       // set all to default pin mode
            PSD_reg.DRIVE_A = 0x00;         // set to default CMOS push-pull and normal slew rate
            PSD_reg.DATAOUT_A = 0x01;       // set LC* off
    
            PSD_reg.DIRECTION_B = 0xF0;     // set PB4..PB7 (A12..A15) as outputs
            PSD_reg.OUTENABLE_B = 0xF0; // enable port pins as outputs if bit = 1
            PSD_reg.CONTROL_B = 0xF0;       // set PB4..PB7 (A12..A15) as latched outputs - high nibble
            PSD_reg.DRIVE_B = 0x00;         // set to default CMOS push-pull and normal slew rate
            PSD_reg.DATAOUT_B = 0x00;       // set all OFF
    
            PSD_reg.DIRECTION_C = 0x80;     // set no port pins as outputs
            PSD_reg.OUTENABLE_C = 0x80; // enable port pins as outputs if bit = 1
            PSD_reg.DRIVE_C = 0x00;         // set to default CMOS push-pull and normal slew rate
            PSD_reg.DATAOUT_C = 0x80;       // set 12VPWRDN* to high
    
            PSD_reg.DIRECTION_D = 0x06;     // set no port pins as outputs
            PSD_reg.OUTENABLE_D = 0x06; // enable port pins as outputs if bit = 1
            PSD_reg.DRIVE_D = 0x00;         // set to default CMOS push-pull and normal slew rate
            PSD_reg.DATAOUT_D = 0x06;       // set DTMF CS* and the Status LED high
    }
    
    // EOF Main.c
    
    /*
            Main.h
            v1.0
            27 April 2008
    
            Copyright 04/27/08, Stephen J. Blair
    
            Header file for the main loop
    
    */
    #ifndef _main_h_
    #define _main_h_
    
    #include "upsd3300.h"
    #include "upsd3300_hardware.h"
    
    void InitIOpins(void);
    
    #endif
    
    // EOF Main.h
    
    /*--------------------------------------------------------------------------
    upsd_sio.c
    
    Version:
    October 27, 2004 Version 0.1
    
    Dependencies: None.
    
    Description:
    UART0 Initialization routine.
    
    Note: the com_baudrate() function should be updated for more flexibility
    for setting the baud rate.  Currently it is fixed and doesn't take into
    account FREQ_OSC found in upsd3xxx_hardware.h file.
    
    Copyright (c) 2004 ST Microelectronics
    
    This example demo code is provided as is and has no warranty,
    implied or otherwise.  You are free to use/modify any of the provided
    code at your own risk in your applications with the expressed limitation
    of liability (see below) so long as your product using the code contains
    at least one uPSD product (device).
    
    LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR
    AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
    INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
    CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
    OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    --------------------------------------------------------------------------*/
    #include "upsd3300.h"
    #include "upsd_SIO.h"
    
    #define USE_TIMER2  //Select timer for baud rate generator
    #define BAUD_19200
    //#define BAUD_115200
    
    // setup TIMER1 to generate the proper baud rate
    void com_baudrate (void)
    {
    #ifdef USE_TIMER1
            TI = 0 ;
            // set timer 1 up as a baud rate generator
            TR1 = 0;                        // stop timer 1
            ET1 = 0;                        // disable timer 1 interrupt
            PCON |= 0x80;           // 0x80=SMOD: set serial baudrate doubler
            TMOD &= ~0xF0;              // clear timer 1 mode bits
            TMOD |= 0x20;           // put timer 1 into MODE 2
    
            // magic formula: (unsigned char) (256 - (OSC_FREQ / (16L * 4L * baudrate)));
            TH1 = -11;                      //for 19200 bps
            TL1 = 0x00;
            TR1 = 1;                        // start timer 1
    #endif
    #ifdef USE_TIMER2
            TI = 0 ;
    #ifdef BAUD_19200
            RCAP2H = 0xFF;//Sets baud rate at 19200
            RCAP2L = 0xBF;//for both UART0 and UART1
    #endif
    #ifdef BAUD_115200
            RCAP2H = 0xFF;//Sets baud rate at 19200
            RCAP2L = 0xF5;//for both UART0 and UART1
    #endif
    
            T2CON = 0x34; //Sets timer2 on, UART0 TCKL and RCKL, timer, reload
    
            SCON0 = 0x74;
    
    #endif
    }
    //------------------------------------------------------------------------------
    
    // initialize the serial port
    void com_initialize (void)
    {
            com_baudrate(); // setup TIMER1 to generate the proper baud rate
    
            // setup serial port registers.
            SM0 = 0;
            SM1 = 1;                // serial port MODE 1
            SM2 = 0;
            REN = 1;                // enable serial receiver
            TI = 0;                 // clear transmit flag
            RI = 0;                 // clear receive flag
    
            ES=0;           //serial interrupts disabled
            PS=0;           //serial interrupts - low priority
            IPA = 0x00;             // reset others devices' priorities
            P3SFS |= 0x03;  // enable alternative function (UART RX & TX) of P3 pins
    
            // Other uPSD init items...
    
            IE |= 0xC0;   // Enable Global and Debug Interrupts...
    
            EA = 1;         // enable interrupts
    }
    //------------------------------------------------------------------------------
    
    // EOF
    
    // upsd_SIO.h
    //
    #ifndef __SIO_H__
    #define __SIO_H__
    
    void com_initialize (void);
    void com_baudrate (void);
    //void com_putstring (unsigned char *str, int len);
    //int com_getstring (char *buf);
    
    #endif
    
    // EOF upsd_SIO.h
    

  • P3.1 UART0-TXD to MAX232 T1IN to T1OUT to TXD on DB-9
    P3.0 UART0-RXD to MAX232 R1OUT to R1IN to RXD on DB-9
    DB-9 pin 5 to GND

  • are you using the correct cable, some connections need R and T crossed, some do not. If you use std DB9 pinning (BTW it is not a DB :), althought everyboddy and his brother calls it that) you need R and T crossed in the cable or T and T will connect.

    Erik

  • I thought this might be it at first too, but the 4 port serial card takes care of the pin swapping.

  • Stephen;
    As Erik points out, you need to define your target board RS232 connections.
    I assume that you are building your target system and we are not talking of an eval board from some vendor.
    You need to decide if your system will be a DCE connection or a DTE connection.
    The PC is normally defined as a DCE and an eval board is defined as a DTE in which case the eval connections for Rx and Tx are reversed and you can use a straight through cable. If both ends are defined as DCE, then you will need a cable reversing pins Rx and TX called a 'Null Modem' connection.
    Google RS232 and you will get several hits on proper pin definitions.
    It sounds to me that you might want your target board defined as DCE so talking to a PC with something like Hyperterminal, you will need a Null Modem cable. Of course Hyperterminal doesn't care what connection you have. I was just using that as an example.
    But if you plan to connect to some accessory, it most likly will be a DTE and your target should be a DCE.
    Bradford

  • Stephen;
    I was out rambling with my typing and did not read your post about the four port card. Please disregard my post. Sorry about that.
    Bradford

  • My PC is DTE. Pin 3 on the DB9 is TXD. I verified this with my oscilloscope. I've got the uPSD3354D wire-wrapped and pin 2 on its DB9 is TXD. You definitely had me checking. It's been a while since I've worked with this board.

  • .. I can't say with certainty re printf.

    BUT I rcall that printf uses putchar (which i don't use either) and tend to recall that there is something you need to do to "install" or "activate" it.

    also, are you sure that TH1 = -11, TL1 =0 is correct verify using the Kiel budrate generator http://www.keil.com/c51/baudrate.asp

    Erik

  • 19.2 is impossible using T1, you need another xtal or use T2

  • I'm using Timer2 to get the 19,200 baud. I tried adding the line:

    TI = 1;

    before:

    printf("Testing");

    In the Keil simulator, I got "Testing" in the UART #1 debug window. On the actual board I keep getting a never ending stream of spaces.

  • The simulator will not have to decode the output from the simulated UART.

    When testing serial communication on real hardware, you should always verify the baudrate with an oscilloscope. That will catch rounding or spelling errors that may result in incorrect baudrates. Even when the PC is able to receive data, the baudrate should be checked - only with a perfect baudrate will the receiver have maximum probability of correctly receiving the data in a noisy environment.

    Anyway - if the PC only shows spaces, the scope should tell what is actually sent on the serial cable.