hello.c

00001 /* hello.c -- Simple Hello World for 68HC11 bootstrap mode
00002    Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
00003    Written by Stephane Carrez (stcarrez@nerim.fr)
00004 
00005 This file is part of GEL.
00006 
00007 GEL is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GEL is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GEL; see the file COPYING.  If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA.  */
00021 
00073 /* Part 1:  68HC11 Definitions.
00074 
00075    This part defines several flags and values to access the
00076    68HC11 SIO registers.  The SIO registers are mapped in memory
00077    and are therefore accessed as a global variable.
00078 
00079    The complete list of flags are available when you include
00080    the following file:
00081 
00082    #include <sys/ports.h>
00083 
00084    They are defined in <asm-m68hc11/ports_def_F.h>,
00085    <asm-m68hc11/ports_def_E.h> or <asm-m68hc12/ports_def.h>
00086    depending on the microcontroller.
00087 
00088 */
00089 #define M6811_BAUD      0x2B    /* SCI Baud register */
00090 #define M6811_SCCR1     0x2C    /* SCI Control register 1 */
00091 #define M6811_SCCR2     0x2D    /* SCI Control register 2 */
00092 #define M6811_SCSR      0x2E    /* SCI Status register */
00093 #define M6811_SCDR      0x2F    /* SCI Data (Read => RDR, Write => TDR) */
00094 
00095 /* Flags of the SCCR2 register.  */
00096 #define M6811_TE        0x08    /* Transmit Enable */
00097 #define M6811_RE        0x04    /* Receive Enable */
00098 
00099 /* Flags of the SCSR register.  */
00100 #define M6811_TDRE      0x80    /* Transmit Data Register Empty */
00101 
00102 /* Flags of the BAUD register.  */
00103 #define M6811_SCP1      0x20    /* SCI Baud rate prescaler select */
00104 #define M6811_SCP0      0x10
00105 #define M6811_SCR2      0x04    /* SCI Baud rate select */
00106 #define M6811_SCR1      0x02
00107 #define M6811_SCR0      0x01
00108 
00109 #define M6811_BAUD_DIV_1        (0)
00110 #define M6811_BAUD_DIV_3        (M6811_SCP0)
00111 #define M6811_BAUD_DIV_4        (M6811_SCP1)
00112 #define M6811_BAUD_DIV_13       (M6811_SCP1|M6811_SCP0)
00113 
00114 #define M6811_DEF_BAUD M6811_BAUD_DIV_4 /* 1200 baud */
00115 
00116 /* The I/O registers are represented by a volatile array.
00117    Address if fixed at link time.  For this particular example,
00118    the _io_ports address is defined in the `memory.x' file.  */
00119 extern volatile unsigned char _io_ports[];
00120 
00121 /* Part 2:  68HC11 SIO Operations.
00122 
00123    This part defines some functions to write characters
00124    on the SIO.  They access the IO register through the
00125    `io_ports' global variable.
00126 
00127    These operations can be used in a program by using
00128    the following include:
00129 
00130    #include <sys/sio.h>
00131 
00132 */
00144 static inline void
00145 serial_send (char c)
00146 {
00147   /* Wait until the SIO has finished to send the character.  */
00148   while (!(_io_ports[M6811_SCSR] & M6811_TDRE))
00149     continue;
00150 
00151   _io_ports[M6811_SCDR] = c;
00152   _io_ports[M6811_SCCR2] |= M6811_TE;
00153 }
00154 
00155 void
00156 serial_print (const char *msg)
00157 {
00158   while (*msg != 0)
00159     serial_send (*msg++);
00160 }
00161 
00162 
00163 /* Part 3:  Hello World
00164 
00165    When the function 'main' is entered, the stack pointer is
00166    initialized, the global variables are initialized but the
00167    SIO as well as other 68HC11 devices are not yet initialized.
00168    In this example, we first configure the SIO by setting
00169    the baud rate and the character format.  The SIO must then
00170    be started by enabling the transmitter and receiver.
00171 
00172    The SIO initialization is inlined here for clarity but it
00173    is implemented by the 'serial_init' operation available when
00174    <sys/sio.h> is included.
00175 
00176    Once the SIO is initialized, we can write messages using
00177    serial_print().
00178 
00179    Note: In this example, the main() function returns and this will give
00180    back control to the startup code which will in turn call exit().  The
00181    exit() will loop forever arround a 'wai' instruction.  Indeed, a real
00182    68HC11 hardware has no way to exit!
00183 */
00184 
00185 int
00186 main ()
00187 {
00188   /* Configure the SCI to send at M6811_DEF_BAUD baud.  */
00189   _io_ports[M6811_BAUD] = M6811_DEF_BAUD;
00190 
00191   /* Setup character format 1 start, 8-bits, 1 stop.  */
00192   _io_ports[M6811_SCCR1] = 0;
00193 
00194   /* Enable receiver and transmitter.  */
00195   _io_ports[M6811_SCCR2] = M6811_TE | M6811_RE;
00196 
00197   serial_print ("Hello world!\n");
00198   return 0;
00199 }