|
Next: Pbus Driver Header File,
Up: Firmware Library, dacslib
Previous: ACIA Serial Driver Header
  Contents
The following code implements the ACIA serial driver code. It is very
similar to SCIserial.c.
/*****************************************************************************
* DACS : Distributed Audio Control System
*============================================================================
* File: ACIAserial.c
* Author: Stephen S. Richardson
* Date Created: 07.14.97
* Environment: ICC11 v4.0, 68HC11 target
* Build: library, not standalone
*============================================================================
* The code, executables, documentation, firmware images, and all related
* material of DACS are
* Copyright (C) 1997 Stephen S. Richardson - ALL RIGHTS RESERVED
*****************************************************************************
* Source code control:
*
* $Id: ACIAserial.c,v 1.1 1997/07/23 22:12:36 prefect Exp prefect $
*
*****************************************************************************/
#include <hc11.h>
#include "ACIAserial.h"
#ifdef _MIXER
#include "pbusdefn.h"
#endif
/*****************************************************************************
* ACIA_prep_raw
*
* initializes a raw frame
*****************************************************************************/
void ACIA_prep_raw (struct raw_frame *raw)
{
int i;
raw->len=0;
raw->cur=0;
raw->done=0;
raw->dleflag=0;
raw->stflag=0;
for (i=0;i<MAXPAYLOAD;i++) raw->data[i]=0;
}
/*****************************************************************************
* ACIA_prep_cooked
*
* initializes a cooked frame
*****************************************************************************/
void ACIA_prep_cooked (struct cooked_frame *cooked)
{
int i;
cooked->len=0;
cooked->cur=0;
cooked->done=1;
for (i=0;i<MAXFRLEN;i++) cooked->data[i]=0;
}
/*****************************************************************************
* ACIA_data_to_cooked
*
* stuffs data into a cooked frame, setting parameters, etc. output frame
* is suitable to be directly output.
*****************************************************************************/
void ACIA_data_to_cooked (char *data, int len, struct cooked_frame *cooked)
{
int i=0, j=0;
char *p;
/* start of frame: DLE+STX */
cooked->data[j++]=DLE;
cooked->data[j++]=STX;
/* payload of frame (character stuffed) */
p=data;
for (i=0;i<len;i++) {
if (*p == DLE) {
cooked->data[j++]=DLE;
cooked->data[j++]=DLE;
p++;
} else {
cooked->data[j++]=*p;
p++;
}
}
/* end of frame: DLE+ETX */
cooked->data[j++]=DLE;
cooked->data[j++]=ETX;
/* set length and other parameters */
cooked->len=j;
cooked->cur=0;
cooked->done=0;
}
/*****************************************************************************
* ACIA_service
*
* perform necessary ACIA operations to manipulate incoming and outgoing
* frames, using a raw frame as an input buffer
*****************************************************************************/
int ACIA_service (struct raw_frame *inraw, struct cooked_frame *outfr)
{
unsigned char ch;
/* outgoing serial data & ACIA output port !busy? */
if ( (ACIASTAT&0x10) && (outfr->done==0) ) {
#ifdef _MIXER
PBC_PC^=0x08;
#endif
ACIADATA=outfr->data[outfr->cur]; /* output the current byte */
/* have we transmitted all of it yet? */
if (++outfr->cur < outfr->len) {
/* not yet.. */
} else {
/* yes */
outfr->done = 1;
}
#ifdef _MIXER
PBC_PC&=~0x08;
#endif
}
/* incoming data on ACIA and unfinished inraw frame? */
if ( (ACIASTAT&0x08) && (inraw->done==0) ) {
/* -- yes, get and fill in the next byte */
#ifdef _MIXER
PBC_PC^=0x04;
#endif
ch = ACIADATA;
if (inraw->dleflag) {
/* the last byte received was a DLE */
if (ch == DLE) {
/* stuffed character */
if (inraw->stflag == STX) {
/* save it if we're mid-frame */
inraw->data[inraw->cur] = DLE;
inraw->dleflag=0;
if (++inraw->cur < MAXPAYLOAD) {
} else {
inraw->done = ERRTOOBIG;
}
}
} else if (ch == STX) {
/* start of frame */
inraw->done = 0;
inraw->cur = 0;
inraw->dleflag=0;
inraw->stflag=STX;
} else if (ch == ETX) {
/* end of frame */
inraw->done = 1;
inraw->dleflag=0;
inraw->stflag=0;
}
} else {
if (ch == DLE) {
/* first DLE */
inraw->dleflag = 1;
} else {
/* other data */
if (inraw->stflag == STX) {
/* save it if we're mid-frame */
inraw->data[inraw->cur] = ch;
inraw->dleflag=0;
if (++inraw->cur < MAXPAYLOAD) {
} else {
inraw->done = ERRTOOBIG;
}
}
}
}
#ifdef _MIXER
PBC_PC&=~0x04;
#endif
}
}
/*****************************************************************************
* ACIA_poll_in
*
* polled ACIA input. returns 1 if there was actually a character to get.
*****************************************************************************/
int ACIA_poll_in (unsigned char *c)
{
if (ACIASTAT&0x08) {
*c=ACIADATA;
return 1;
} else {
return 0;
}
}
/*****************************************************************************
* ACIA_block_in
*
* blocking ACIA input. returns character.
*****************************************************************************/
char ACIA_block_in (void)
{
while (!(ACIASTAT&0x08));
return (ACIADATA);
}
/*****************************************************************************
* ACIA_poll_in
*
* polled ACIA input. returns 1 if there was actually a character to get.
*****************************************************************************/
void ACIA_chout (unsigned char ch)
{
while (!(ACIASTAT & 0x10));
ACIADATA = ch;
}
/*****************************************************************************
* ACIA_out
*
* ACIA output (blocking)
*****************************************************************************/
void ACIA_out (char *s)
{
char *t=s;
while (*t!=0) {
while (!(ACIASTAT & 0x10));
ACIADATA = *t++;
}
}
/*****************************************************************************
* ACIA_init
*
* initialize ACIA port, 9600 baud, 8-N-1
*****************************************************************************/
void ACIA_init (void)
{
ACIACTRL = 0x1E;
ACIACMD = 0xCB;
}
Steve Richardson
2000-07-06
|
Table of Contents
[Whole document in PDF 1.9MB]
[more photos and information]
|