ARM Technical Support Knowledge Articles

USING 2ND SERIAL PORT (ASC1) ON INFINEON XC16X DEVICES

Applies to: C166 C Compiler

Answer


Information in this article applies to:


QUESTION

I want to use the second serial port (ASC1) on the Infineon XC167. What must I do to use the ASC1 with my program?

ANSWER

Infineon has added the second serial port (ASC1) on some XC16x devices. ASC1 is almost identical with the ASC0 but its SFR's are at different addresses.

Therefore, the basic character input/output functions defined in GETKEY.C and PUTCHAR.C must be modified to work for ASC1. These functions are also used by printf, scanf, puts and gets.

To modify GETKEY.C and PUTCHAR.C...

  1. Copy the following code into new PUTCHAR.C and GETKEY.C source files.
  2. Set USE_ASC to 1 for ASC1 in both files.
  3. Include the new modified PUTCHAR.C and GETKEY.C files in your project.
  4. Initialize ASC1 in your main program. See HELLO.C example below.
  5. Re-build your project using the new GETKEY.C and PUTCHAR.C to use ASC1.

PUTCHAR.C

/***********************************************************************/
/*  This file is part of the C166 Compiler package                     */
/*  Copyright KEIL ELEKTRONIK GmbH 1992-2003                           */
/***********************************************************************/
/*                                                                     */
/*  PUTCHAR.C:  This routine is the general character output of C166.  */
/*  You may add this file to a uVision project.                        */
/*                                                                     */
/*  To translate this file use C166 with the following invocation:     */
/*                                                                     */
/*     C166 PUTCHAR.C memory model                                     */
/*                                                                     */
/*  To link the modified PUTCHAR.OBJ file to your application use the  */
/*  following L166 invocation:                                         */
/*                                                                     */
/*     L166 your object file list, PUTCHAR.OBJ controls                */
/*                                                                     */
/***********************************************************************/

#include <XC167.H>

#define XON  0x11
#define XOFF 0x13

#define USE_ASC   1       // set to 0 to use ASC0 with XC161, XC164 and XC167
                          // set to 1 to use ASC1 with XC161 and XC167

#if (USE_ASC == 0)
  #define ASCx_TBUF    ASC0_TBUF
  #define ASCx_RBUF    ASC0_RBUF
  #define ASCx_RIC_IR  ASC0_RIC_IR
  #define ASCx_TIC_IR  ASC0_TIC_IR
#elif (USE_ASC == 1)
  #define ASCx_TBUF    ASC1_TBUF
  #define ASCx_RBUF    ASC1_RBUF
  #define ASCx_RIC_IR  ASC1_RIC_IR
  #define ASCx_TIC_IR  ASC1_TIC_IR
#else
#error "USE_ASC definition is wrong!"
#endif

/*
 * putchar (full version):  expands '
' into CR LF and handles
 *                          XON/XOFF (Ctrl+S/Ctrl+Q) protocol
 */
signed char putchar (signed char c)  {

  if (c == '
')  {
    if (ASCx_RIC_IR)  {
      if (ASCx_RBUF == XOFF)  {
        do  {
          ASCx_RIC_IR = 0;
          while (!ASCx_RIC_IR);
        }
        while (ASCx_RBUF != XON);
        ASCx_RIC_IR = 0;
      }
    }
    while (!ASCx_TIC_IR);
    ASCx_TIC_IR = 0;
    ASCx_TBUF = 0x0d;                         /* output CR  */
  }
  if (ASCx_RIC_IR)  {
    if (ASCx_RBUF == XOFF)  {
      do  {
        ASCx_RIC_IR = 0;
        while (!ASCx_RIC_IR);
      }
      while (ASCx_RBUF != XON);
      ASCx_RIC_IR = 0;
    }
  }
  while (!ASCx_TIC_IR);
  ASCx_TIC_IR = 0;
  return (ASCx_TBUF = c);
}

#if 0         // comment out versions below
/*
 * putchar (basic version): expands '
' into CR LF
 */
char putchar (char c)  {
  if (c == '
')  {
    while (!ASCx_TIC_IR);
    ASCx_TIC_IR = 0;
    ASCx_TBUF = 0x0d;                         /* output CR  */
  }
  while (!ASCx_TIC_IR);
  ASCx_TIC_IR = 0;
  return (ASCx_TBUF = c);
}

/*
 * putchar (mini version): outputs charcter only
 */
char putchar (char c)  {
  while (!ASCx_TIC_IR);
  ASCx_TIC_IR = 0;
  return (ASCx_TBUF = c);
}
#endif

GETKEY.C

/***********************************************************************/
/*  This file is part of the C166 Compiler package                     */
/*  Copyright KEIL ELEKTRONIK GmbH 1992-2003                           */
/***********************************************************************/
/*                                                                     */
/*  GETKEY.C:  This routine is the general character input of C166.    */
/*  You may add this file to a uVision project.                        */
/*                                                                     */
/*  To translate this file use C166 with the following invocation:     */
/*                                                                     */
/*     C166 GETKEY.C  memory model                                     */
/*                                                                     */
/*  To link the modified GETKEY.OBJ file to your application use the   */
/*  following L166 invocation:                                         */
/*                                                                     */
/*     L166 your object file list, GETKEY.OBJ controls                 */
/*                                                                     */
/***********************************************************************/

#include <XC167.h>

#define USE_ASC   1       // set to 0 to use ASC0 with XC161, XC164 and XC167
                          // set to 1 to use ASC1 with XC161 and XC167

#if (USE_ASC == 0)
  #define ASCx_TBUF    ASC0_TBUF
  #define ASCx_RBUF    ASC0_RBUF
  #define ASCx_RIC_IR  ASC0_RIC_IR
  #define ASCx_TIC_IR  ASC0_TIC_IR
#elif (USE_ASC == 1)
  #define ASCx_TBUF    ASC1_TBUF
  #define ASCx_RBUF    ASC1_RBUF
  #define ASCx_RIC_IR  ASC1_RIC_IR
  #define ASCx_TIC_IR  ASC1_TIC_IR
#else
#error "USE_ASC definition is wrong!"
#endif


signed char _getkey (void)  {
  char c;

  while (!ASCx_RIC_IR);
  c = (char) ASCx_RBUF;
  ASCx_RIC_IR = 0;
  return (c);
}

HELLO.C

/*-------------------------------------------------------------------------
HELLO.C: adapted for Infineon XC16x devices

Copyright 1995-2003 Keil Software, Inc.
-------------------------------------------------------------------------*/

#include <stdio.h>                /* standard I/O .h-file                */
#include <XC161.h>                /* special function register XC161     */
#include <math.h>

#define USE_ASC   1     /* set to 0 to use ASC0                          */
                        /* set to 1 to use ASC1                          */

/****************/
/* main program */
/****************/
void main (void)  {               /* execution starts here               */
                                  /* initialize the serial interface     */
#ifndef Monitor         /* do not initialize if you use Monitor-166      */

#if (USE_ASC == 0)
  P3  |= 0x0400;        /* SET PORT 3.10 OUTPUT LATCH (TXD)              */
  DP3 |= 0x0400;        /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT)  */
  DP3 &= 0xF7FF;        /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */
  ASC0_TIC = 0x80;      /* SET TRANSMIT INTERRUPT FLAG                   */
  ASC0_RIC = 0x00;      /* DELETE RECEIVE INTERRUPT FLAG                 */
  ASC0_BG  = 0x40;      /* SET BAUDRATE TO 9600 BAUD @ 20MHz             */
  ASC0_CON = 0x8011;    /* SET SERIAL MODE                               */
  ALTSEL0P3 |= 0x0C00;  /* Configure port pins for serial interface 0    */
#else
  P3  |= 0x0001;        /* SET PORT 3.0 OUTPUT LATCH (TXD)               */
  DP3 |= 0x0001;        /* SET PORT 3.0 DIRECTION CONTROL (TXD OUTPUT)   */
  DP3 &= 0xFFFD;        /* RESET PORT 3.1 DIRECTION CONTROL (RXD INPUT)  */
  ASC1_TIC = 0x80;      /* SET TRANSMIT INTERRUPT FLAG                   */
  ASC1_RIC = 0x00;      /* DELETE RECEIVE INTERRUPT FLAG                 */
  ASC1_BG  = 0x40;      /* SET BAUDRATE TO 9600 BAUD @ 20MHz             */
  ASC1_CON = 0x8011;    /* SET SERIAL MODE                               */
  ALTSEL0P3 |= 0x0003;  /* Configure port pins for serial interface 1    */
#endif

#endif


  printf ("Hello World
");  /* the 'printf' function call               */
  while (1) {                /* An embedded program does not stop and    */
    ;  /* ... */             /* never returns.  We've used an endless    */
  }                          /* loop.  You may wish to put in your own   */
}                            /* code were we've printed the dots (...).  */

MORE INFORMATION

SEE ALSO

Article last edited on: 2007-03-27 11:01:59

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential