home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / HITECH-C / MOTOROLA.EXE / FEAT6805.C < prev    next >
C/C++ Source or Header  |  1993-04-21  |  7KB  |  235 lines

  1. #include    <intrpt.h>
  2.  
  3. /*
  4.  *    "feat6805.c"    HI-TECH Software, January 1993
  5.  *
  6.  *    This source file demonstrates some of the special features
  7.  *    of the HI-TECH 6805/68HC05 C Cross Compiler.  This sample code
  8.  *    is a basic outline for a serial to parallel converter using
  9.  *    the MC68HC05C8 processor.  This kind of application is typical
  10.  *    of the sort of code which can be written rapidly using a C
  11.  *    compiler with a fraction of the effort required to produce an
  12.  *    equivalent application in assembler code.
  13.  *
  14.  *    The file "feat6805.dmp" is a hex dump of a binary file produced
  15.  *    for "feat6805.c" by the full version of the compiler. The binary
  16.  *    file uses only internal RAM from $50 to $FF and ROM from $1E00
  17.  *    to $1FFF and was produced using the command:
  18.  *
  19.  *    c05 -O -Zg -Ofeat6805.bin -A1E00,200,50,0,0 feat6805.c
  20.  *
  21.  *    Note the small size of the binary produced for this code: less than
  22.  *    512 bytes of ROM have been consumed.  The 68HC05C8 has over 7000
  23.  *    bytes of user PROM, so applications much more complex than this
  24.  *    example could easily be created with HI-TECH C.
  25.  *    
  26.  *    To generate the best possible code from this source file, select
  27.  *    68HC05 code generation from the "Options" menu and "Full Optimization"
  28.  *    from the "Optimization" menu.  This will demonstrate the quality of
  29.  *    code which can be obtained using HI-TECH C.
  30.  *
  31.  *    HI-TECH C has a number of features designed to make programming
  32.  *    embedded processors simpler and more efficient, these include:
  33.  *
  34.  *    interrupt functions: interrupt handlers may be written entirely
  35.  *                 in C (no messy assembler code required).
  36.  *                 Interrupt functions automatically preserve
  37.  *                 all registers and "temp" locations used.
  38.  *
  39.  *    absolute variables:  variables of any type (even complex
  40.  *                 structures and arrays) can be placed at
  41.  *                 any absolute address in memory - great
  42.  *                 for handling memory mapped devices.
  43.  *
  44.  *    in-line assembler:   assembler code can be place in line.  This
  45.  *                 is useful for accessing special instructions.
  46.  *
  47.  *    register arguments:  some function arguments are passed in
  48.  *                 the X register.  Register based argument
  49.  *                 passing is faster and more compact than
  50.  *                 the standard memory based argument passing.
  51.  */
  52.  
  53. #ifndef    m6805
  54. #error    This program should be compiled to 6805 or 68HC05 code
  55. #endif
  56.  
  57. /*
  58.  *    I/O ports used.  These declarations for MC68HC05C8
  59.  */
  60.  
  61. volatile unsigned char    PORT_A   @ 0x00; /* Port A data */
  62. volatile unsigned char    PORT_B   @ 0x01; /* Port B data */
  63. volatile unsigned char    DDR_A    @ 0x04; /* Port A DDR */
  64. volatile unsigned char    DDR_B    @ 0x05; /* Port B DDR */
  65.  
  66. /*
  67.  *    MC68HC05C8 SCI serial port
  68.  */
  69.  
  70. volatile unsigned char    SCI_BAUD @ 0x0D; /* Serial baud rate */
  71. volatile unsigned char    SCCR1    @ 0x0E; /* Serial control 1 */
  72. volatile unsigned char    SCCR2    @ 0x0F; /* Serial control 2 */
  73. volatile unsigned char    SCSR     @ 0x10; /* Serial status */
  74. volatile unsigned char    SCDAT    @ 0x11; /* Serial data */
  75.  
  76. #define    SER_VEC        0x1FF6    /* Serial interrupt vector */
  77.  
  78. #define    BAUD_RATE    0xC0    /* == 4800 baud @ 2Mhz */
  79.  
  80. /*
  81.  *    SCCR2 register bit declarations
  82.  */
  83.  
  84. #define    TIE        0x80    /* tx interrupt enable */
  85. #define    TCIE        0x40    /* tx complete interrupt enable */
  86. #define    RIE        0x20    /* rx interrupt enable */
  87. #define    ILIE        0x10    /* idle line interrupt enable */
  88. #define    TE        0x08    /* transmit enable */
  89. #define    RE        0x04    /* receive enable */
  90. #define    RWU        0x02    /* receiver wakeup function */
  91. #define    BRK        0x01    /* send break */
  92.  
  93. /*
  94.  *    Global variables, buffers, etc ...
  95.  */
  96.  
  97. #define    BUFSIZE        64        /* circular buffer size */
  98. #define    BUFMASK        63        /* buffer wraparound mask */
  99.  
  100. near unsigned char    serbuf[BUFSIZE]; /* circular buffer */
  101. near unsigned char    ri_ptr, ro_ptr;     /* head, tail pointers */
  102.  
  103. /*
  104.  *    interrupt void    rx_intr(void)
  105.  *
  106.  *    Serial interrupt handler.  Takes the incoming character from
  107.  *    the serial port and places it in the circular buffer.  If
  108.  *    the buffer is full, the incoming character is discarded.
  109.  *
  110.  *    Further processing to correctly handle framing errors, overrun,
  111.  *    etc., should be added here.
  112.  */
  113.  
  114. interrupt void
  115. rx_intr(void)
  116. {
  117.     serbuf[ri_ptr++] = SCDAT;
  118.     ri_ptr &= BUFMASK;
  119.     if (ro_ptr == ri_ptr) {    /* buffer overflow ? */
  120.         --ri_ptr;    /* discard byte received */
  121.         ri_ptr &= BUFMASK;
  122.     }
  123. }
  124.  
  125. /*
  126.  *    unsigned char    sio_char_avail(void)
  127.  *
  128.  *    Return TRUE (non zero) if a character is available from
  129.  *    the circular buffer, FALSE (zero) if no character is available.
  130.  */
  131.  
  132. unsigned char
  133. sio_char_avail(void)
  134. {
  135.     return (ri_ptr != ro_ptr);
  136. }
  137.  
  138. /*
  139.  *    unsigned char    sio_get_char(void)
  140.  *
  141.  *    returns one char from the tail of the circular buffer.  Assumes
  142.  *    that a char is available.  Call sio_char_avail() above to
  143.  *    determine whether a character is available.
  144.  */
  145.  
  146. unsigned char
  147. sio_get_char(void)
  148. {
  149.     unsigned char    ch;
  150.  
  151.     di();
  152.     ch = serbuf[ro_ptr++];
  153.     ro_ptr &= BUFMASK;
  154.     ei();
  155.     return ch;
  156. }
  157.  
  158. /*
  159.  *    void    port_a_send(unsigned char ch)
  160.  *
  161.  *    Transmit a character via PORT_A if bit 0 of PORT_B is high,
  162.  *    indicating that a character is available.  This routine also
  163.  *    translates newline (0x0A) into a carriage return (0x0D) and
  164.  *    newline pair.
  165.  */
  166.  
  167. void
  168. port_a_send(unsigned char ch)
  169. {
  170.     if (ch == '\n') {
  171.         while (!(PORT_B & 1))
  172.             continue;
  173.         PORT_A = '\r';
  174.     }
  175.     while (!(PORT_B & 1))    /* wait for handshake */
  176.         continue;
  177.     PORT_A = ch;
  178. }
  179.  
  180. /*
  181.  *    void    device_inits(void)
  182.  *
  183.  *    Perform device initialization.
  184.  *
  185.  *    Set up the incoming serial port, initialize interrupts
  186.  *    Set up PORT_A as 8 output bits, Set up PORT_B, bit 0 as input.
  187.  */
  188.  
  189. static const char    firm_id[] = "\nDemo Firmware V1.0\n";
  190.  
  191. void
  192. device_inits(void)
  193. {
  194.     unsigned char    index;
  195.  
  196.     di();
  197. /* Serial port */
  198.     ROM_VECTOR(SER_VEC, rx_intr);
  199.     SCI_BAUD = BAUD_RATE;
  200.     SCCR1 = 0x00;        /* 8 data bits */
  201.     SCCR2 = TE|RE|RIE;  /* enable tx, rx, rx interrupt */
  202. /* Parallel ports */
  203.     DDR_A = 0xFF;    /* PORT A: all outputs */
  204.     DDR_B = 0x00;    /* PORT B: all input */
  205.     ei();
  206. /* Send initialization signature 0xAA, 0x55 */
  207.     port_a_send(0xAA);
  208.     port_a_send(0x55);
  209. /* Send firmware ident string */
  210.     for (index = 0; firm_id[index] != 0; index++)
  211.         port_a_send(firm_id[index]);
  212. }
  213.  
  214. /*
  215.  *    main()
  216.  *
  217.  *    Control is passed here by the run-time startoff code.  Initialize
  218.  *    all I/O then enter the main processing loop.  As this is a ROM
  219.  *    based application, main() should never exit.
  220.  */
  221.  
  222. main()
  223. {
  224.     device_inits();
  225.     for (;;) {
  226.         if (sio_char_avail())
  227.             port_a_send(sio_get_char());
  228.         /* other processing */
  229.     }
  230. }
  231.  
  232. /*
  233.  *    End of file: "feat6805.c"
  234.  */
  235.