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 >
Wrap
C/C++ Source or Header
|
1993-04-21
|
7KB
|
235 lines
#include <intrpt.h>
/*
* "feat6805.c" HI-TECH Software, January 1993
*
* This source file demonstrates some of the special features
* of the HI-TECH 6805/68HC05 C Cross Compiler. This sample code
* is a basic outline for a serial to parallel converter using
* the MC68HC05C8 processor. This kind of application is typical
* of the sort of code which can be written rapidly using a C
* compiler with a fraction of the effort required to produce an
* equivalent application in assembler code.
*
* The file "feat6805.dmp" is a hex dump of a binary file produced
* for "feat6805.c" by the full version of the compiler. The binary
* file uses only internal RAM from $50 to $FF and ROM from $1E00
* to $1FFF and was produced using the command:
*
* c05 -O -Zg -Ofeat6805.bin -A1E00,200,50,0,0 feat6805.c
*
* Note the small size of the binary produced for this code: less than
* 512 bytes of ROM have been consumed. The 68HC05C8 has over 7000
* bytes of user PROM, so applications much more complex than this
* example could easily be created with HI-TECH C.
*
* To generate the best possible code from this source file, select
* 68HC05 code generation from the "Options" menu and "Full Optimization"
* from the "Optimization" menu. This will demonstrate the quality of
* code which can be obtained using HI-TECH C.
*
* HI-TECH C has a number of features designed to make programming
* embedded processors simpler and more efficient, these include:
*
* interrupt functions: interrupt handlers may be written entirely
* in C (no messy assembler code required).
* Interrupt functions automatically preserve
* all registers and "temp" locations used.
*
* absolute variables: variables of any type (even complex
* structures and arrays) can be placed at
* any absolute address in memory - great
* for handling memory mapped devices.
*
* in-line assembler: assembler code can be place in line. This
* is useful for accessing special instructions.
*
* register arguments: some function arguments are passed in
* the X register. Register based argument
* passing is faster and more compact than
* the standard memory based argument passing.
*/
#ifndef m6805
#error This program should be compiled to 6805 or 68HC05 code
#endif
/*
* I/O ports used. These declarations for MC68HC05C8
*/
volatile unsigned char PORT_A @ 0x00; /* Port A data */
volatile unsigned char PORT_B @ 0x01; /* Port B data */
volatile unsigned char DDR_A @ 0x04; /* Port A DDR */
volatile unsigned char DDR_B @ 0x05; /* Port B DDR */
/*
* MC68HC05C8 SCI serial port
*/
volatile unsigned char SCI_BAUD @ 0x0D; /* Serial baud rate */
volatile unsigned char SCCR1 @ 0x0E; /* Serial control 1 */
volatile unsigned char SCCR2 @ 0x0F; /* Serial control 2 */
volatile unsigned char SCSR @ 0x10; /* Serial status */
volatile unsigned char SCDAT @ 0x11; /* Serial data */
#define SER_VEC 0x1FF6 /* Serial interrupt vector */
#define BAUD_RATE 0xC0 /* == 4800 baud @ 2Mhz */
/*
* SCCR2 register bit declarations
*/
#define TIE 0x80 /* tx interrupt enable */
#define TCIE 0x40 /* tx complete interrupt enable */
#define RIE 0x20 /* rx interrupt enable */
#define ILIE 0x10 /* idle line interrupt enable */
#define TE 0x08 /* transmit enable */
#define RE 0x04 /* receive enable */
#define RWU 0x02 /* receiver wakeup function */
#define BRK 0x01 /* send break */
/*
* Global variables, buffers, etc ...
*/
#define BUFSIZE 64 /* circular buffer size */
#define BUFMASK 63 /* buffer wraparound mask */
near unsigned char serbuf[BUFSIZE]; /* circular buffer */
near unsigned char ri_ptr, ro_ptr; /* head, tail pointers */
/*
* interrupt void rx_intr(void)
*
* Serial interrupt handler. Takes the incoming character from
* the serial port and places it in the circular buffer. If
* the buffer is full, the incoming character is discarded.
*
* Further processing to correctly handle framing errors, overrun,
* etc., should be added here.
*/
interrupt void
rx_intr(void)
{
serbuf[ri_ptr++] = SCDAT;
ri_ptr &= BUFMASK;
if (ro_ptr == ri_ptr) { /* buffer overflow ? */
--ri_ptr; /* discard byte received */
ri_ptr &= BUFMASK;
}
}
/*
* unsigned char sio_char_avail(void)
*
* Return TRUE (non zero) if a character is available from
* the circular buffer, FALSE (zero) if no character is available.
*/
unsigned char
sio_char_avail(void)
{
return (ri_ptr != ro_ptr);
}
/*
* unsigned char sio_get_char(void)
*
* returns one char from the tail of the circular buffer. Assumes
* that a char is available. Call sio_char_avail() above to
* determine whether a character is available.
*/
unsigned char
sio_get_char(void)
{
unsigned char ch;
di();
ch = serbuf[ro_ptr++];
ro_ptr &= BUFMASK;
ei();
return ch;
}
/*
* void port_a_send(unsigned char ch)
*
* Transmit a character via PORT_A if bit 0 of PORT_B is high,
* indicating that a character is available. This routine also
* translates newline (0x0A) into a carriage return (0x0D) and
* newline pair.
*/
void
port_a_send(unsigned char ch)
{
if (ch == '\n') {
while (!(PORT_B & 1))
continue;
PORT_A = '\r';
}
while (!(PORT_B & 1)) /* wait for handshake */
continue;
PORT_A = ch;
}
/*
* void device_inits(void)
*
* Perform device initialization.
*
* Set up the incoming serial port, initialize interrupts
* Set up PORT_A as 8 output bits, Set up PORT_B, bit 0 as input.
*/
static const char firm_id[] = "\nDemo Firmware V1.0\n";
void
device_inits(void)
{
unsigned char index;
di();
/* Serial port */
ROM_VECTOR(SER_VEC, rx_intr);
SCI_BAUD = BAUD_RATE;
SCCR1 = 0x00; /* 8 data bits */
SCCR2 = TE|RE|RIE; /* enable tx, rx, rx interrupt */
/* Parallel ports */
DDR_A = 0xFF; /* PORT A: all outputs */
DDR_B = 0x00; /* PORT B: all input */
ei();
/* Send initialization signature 0xAA, 0x55 */
port_a_send(0xAA);
port_a_send(0x55);
/* Send firmware ident string */
for (index = 0; firm_id[index] != 0; index++)
port_a_send(firm_id[index]);
}
/*
* main()
*
* Control is passed here by the run-time startoff code. Initialize
* all I/O then enter the main processing loop. As this is a ROM
* based application, main() should never exit.
*/
main()
{
device_inits();
for (;;) {
if (sio_char_avail())
port_a_send(sio_get_char());
/* other processing */
}
}
/*
* End of file: "feat6805.c"
*/