mirror of
https://github.com/deadw00d/AROS.git
synced 2025-12-09 16:00:35 +00:00
710 lines
17 KiB
C
710 lines
17 KiB
C
/*
|
|
Copyright (C) 1995-2011, The AROS Development Team. All rights reserved.
|
|
|
|
Desc: Serial Unit hidd class implementation.
|
|
*/
|
|
|
|
/*
|
|
Right now I am assuming that there is a 1.8432 MHZ crystal connected to
|
|
the 16550 UART.
|
|
*/
|
|
|
|
|
|
#include <asm/io.h>
|
|
#include <asm/amcc440.h>
|
|
|
|
/* the rest are Amiga includes */
|
|
#include <proto/exec.h>
|
|
#include <proto/utility.h>
|
|
#include <proto/oop.h>
|
|
#include <proto/alib.h>
|
|
#include <proto/intuition.h>
|
|
#include <exec/libraries.h>
|
|
#include <exec/ports.h>
|
|
#include <exec/memory.h>
|
|
#include <exec/interrupts.h>
|
|
#include <exec/lists.h>
|
|
|
|
#include <utility/tagitem.h>
|
|
#include <hidd/serial.h>
|
|
#include <hidd/unixio.h>
|
|
#include <hidd/irq.h>
|
|
#include <intuition/preferences.h>
|
|
|
|
#include <devices/serial.h>
|
|
|
|
#include "serial_intern.h"
|
|
|
|
#undef SDEBUG
|
|
#undef DEBUG
|
|
#define SDEBUG 0
|
|
#define DEBUG 0
|
|
#include <aros/debug.h>
|
|
|
|
/* The speed of the crystal */
|
|
#define CRYSTAL_SPEED 1843200
|
|
|
|
|
|
static void serialunit_receive_data();
|
|
ULONG serialunit_write_more_data();
|
|
|
|
unsigned char get_lcr(struct HIDDSerialUnitData * data);
|
|
unsigned char get_fcr(ULONG baudrate);
|
|
BOOL set_baudrate(struct HIDDSerialUnitData * data, ULONG speed);
|
|
static void adapt_data(struct HIDDSerialUnitData * data,
|
|
struct Preferences * prefs);
|
|
|
|
static inline void serial_out(struct HIDDSerialUnitData * data,
|
|
int offset,
|
|
int value)
|
|
{
|
|
outb(value, data->baseaddr+offset);
|
|
}
|
|
|
|
static inline void serial_outp(struct HIDDSerialUnitData * data,
|
|
int offset,
|
|
int value)
|
|
{
|
|
outb_p(value, data->baseaddr+offset);
|
|
}
|
|
|
|
static inline unsigned int serial_in(struct HIDDSerialUnitData * data,
|
|
int offset)
|
|
{
|
|
return inb(data->baseaddr+offset);
|
|
}
|
|
|
|
static inline unsigned int serial_inp(struct HIDDSerialUnitData * data,
|
|
int offset)
|
|
{
|
|
return inb_p(data->baseaddr+offset);
|
|
}
|
|
|
|
|
|
|
|
/*************************** Classes *****************************/
|
|
|
|
/* IO bases for every COM port */
|
|
static ULONG bases[] = { UART0_RBR, UART1_RBR, UART2_RBR, UART3_RBR };
|
|
|
|
/******* SerialUnit::New() ***********************************/
|
|
OOP_Object *PPC4xxSerUnit__Root__New(OOP_Class *cl, OOP_Object *obj, struct pRoot_New *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data;
|
|
struct TagItem *tag, *tstate;
|
|
ULONG unitnum = 0;
|
|
|
|
EnterFunc(bug("SerialUnit::New()\n"));
|
|
|
|
tstate = msg->attrList;
|
|
while ((tag = NextTagItem(&tstate)))
|
|
{
|
|
ULONG idx;
|
|
|
|
#define csd CSD(cl->UserData)
|
|
if (IS_HIDDSERIALUNIT_ATTR(tag->ti_Tag, idx))
|
|
#undef csd
|
|
{
|
|
switch (idx)
|
|
{
|
|
case aoHidd_SerialUnit_Unit:
|
|
unitnum = (ULONG)tag->ti_Data;
|
|
break;
|
|
}
|
|
}
|
|
|
|
} /* while (tags to process) */
|
|
|
|
obj = (OOP_Object *)OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
|
|
|
|
if (obj)
|
|
{
|
|
struct IntuitionBase * IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
|
|
data = OOP_INST_DATA(cl, obj);
|
|
|
|
data->baseaddr = bases[unitnum];
|
|
|
|
if (NULL != IntuitionBase) {
|
|
struct Preferences prefs;
|
|
GetPrefs(&prefs,sizeof(prefs));
|
|
data->baudrate = prefs.BaudRate;
|
|
adapt_data(data, &prefs);
|
|
CloseLibrary((struct Library *)IntuitionBase);
|
|
} else {
|
|
data->datalength = 8;
|
|
data->parity = FALSE;
|
|
data->baudrate = 9600; /* will be initialize in set_baudrate() */
|
|
}
|
|
data->unitnum = unitnum;
|
|
|
|
Disable();
|
|
CSD(cl->UserData)->sd_Unit[data->unitnum] = data;
|
|
Enable();
|
|
|
|
D(bug("Unit %d at 0x0%x\n", data->unitnum, data->baseaddr));
|
|
|
|
/* Wake up UART */
|
|
serial_outp(data, UART_LCR, 0xBF);
|
|
serial_outp(data, UART_EFR, UART_EFR_ECB);
|
|
serial_outp(data, UART_IER, 0);
|
|
serial_outp(data, UART_EFR, 0);
|
|
serial_outp(data, UART_LCR, 0);
|
|
|
|
/* clear the FIFOs */
|
|
serial_outp(data, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
|
|
|
|
/* clear the interrupt registers */
|
|
(void)serial_inp(data, UART_RX);
|
|
(void)serial_inp(data, UART_IIR);
|
|
(void)serial_inp(data, UART_MSR);
|
|
|
|
/* initilize the UART */
|
|
serial_outp(data, UART_LCR, get_lcr(data));
|
|
|
|
serial_outp(data, UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS);
|
|
serial_outp(data, UART_IER, UART_IER_RDI | UART_IER_THRI | UART_IER_RLSI | UART_IER_MSI);
|
|
|
|
/* clear the interrupt registers again ... */
|
|
(void)serial_inp(data, UART_LSR);
|
|
(void)serial_inp(data, UART_RX);
|
|
(void)serial_inp(data, UART_IIR);
|
|
(void)serial_inp(data, UART_MSR);
|
|
|
|
set_baudrate(data, data->baudrate);
|
|
} /* if (obj) */
|
|
|
|
ReturnPtr("SerialUnit::New()", OOP_Object *, obj);
|
|
}
|
|
|
|
/******* SerialUnit::Dispose() ***********************************/
|
|
OOP_Object *PPC4xxSerUnit__Root__Dispose(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg)
|
|
{
|
|
struct HIDDSerialUnitData * data;
|
|
EnterFunc(bug("SerialUnit::Dispose()\n"));
|
|
|
|
data = OOP_INST_DATA(cl, obj);
|
|
|
|
Disable();
|
|
CSD(cl->UserData)->units[data->unitnum] = NULL;
|
|
Enable();
|
|
|
|
/* stop all interrupts */
|
|
serial_outp(data, UART_IER, 0);
|
|
|
|
OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
|
|
ReturnPtr("SerialUnit::Dispose()", OOP_Object *, obj);
|
|
}
|
|
|
|
|
|
|
|
/******* SerialUnit::Init() **********************************/
|
|
BOOL PPC4xxSerUnit__Hidd_SerialUnit__Init(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_Init *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
|
|
EnterFunc(bug("SerialUnit::Init()\n"));
|
|
Disable();
|
|
data->DataReceivedCallBack = msg->DataReceived;
|
|
data->DataReceivedUserData = msg->DataReceivedUserData;
|
|
data->DataWriteCallBack = msg->WriteData;
|
|
data->DataWriteUserData = msg->WriteDataUserData;
|
|
Enable();
|
|
|
|
ReturnBool("SerialUnit::Init()", TRUE);
|
|
}
|
|
|
|
/******* SerialUnit::Write() **********************************/
|
|
ULONG PPC4xxSerUnit__Hidd_SerialUnit__Write(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_Write *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
unsigned char status;
|
|
ULONG len = msg->Length;
|
|
ULONG count = 0;
|
|
|
|
EnterFunc(bug("SerialUnit::Write()\n"));
|
|
|
|
/*
|
|
* If the output is currently stopped just don't do anything here.
|
|
*/
|
|
if (TRUE == data->stopped)
|
|
return 0;
|
|
|
|
status = serial_inp(data, UART_LSR);
|
|
|
|
if (status & UART_LSR_THRE)
|
|
{
|
|
/* write data into FIFO */
|
|
do
|
|
{
|
|
serial_outp(data, UART_TX, msg->Outbuffer[count++]);
|
|
len--;
|
|
} while (len > 0 && serial_inp(data, UART_LSR & UART_LSR_TEMT));
|
|
}
|
|
|
|
ReturnInt("SerialUnit::Write()",ULONG, count);
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
static ULONG valid_baudrates[] =
|
|
{
|
|
2 | LIMIT_LOWER_BOUND,
|
|
115200 | LIMIT_UPPER_BOUND,
|
|
~0
|
|
};
|
|
|
|
|
|
/******* SerialUnit::SetBaudrate() **********************************/
|
|
BOOL PPC4xxSerUnit__Hidd_SerialUnit__SetBaudrate(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_SetBaudrate *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
BOOL valid = FALSE;
|
|
|
|
if (msg->baudrate != data->baudrate)
|
|
{
|
|
valid = set_baudrate(data, msg->baudrate);
|
|
} /* if */
|
|
return valid;
|
|
}
|
|
|
|
static UBYTE valid_datalengths[] =
|
|
{
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
~0
|
|
};
|
|
|
|
/******* SerialUnit::SetParameters() **********************************/
|
|
BOOL PPC4xxSerUnit__Hidd_SerialUnit__SetParameters(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_SetParameters *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
BOOL valid = TRUE;
|
|
int i = 0;
|
|
struct TagItem * tags = msg->tags;
|
|
|
|
while (TAG_END != tags[i].ti_Tag && TRUE == valid)
|
|
{
|
|
switch (tags[i].ti_Tag)
|
|
{
|
|
case TAG_DATALENGTH:
|
|
if ((BYTE)tags[i].ti_Data >= 5 && (BYTE)tags[i].ti_Data <= 8)
|
|
data->datalength = tags[i].ti_Data;
|
|
else
|
|
valid = FALSE;
|
|
break;
|
|
|
|
case TAG_STOP_BITS: /* 3 means 1.5 stopbits (if supported) */
|
|
if (1 == tags[i].ti_Data ||
|
|
2 == tags[i].ti_Data ||
|
|
3 == tags[i].ti_Data)
|
|
data->stopbits = tags[i].ti_Data;
|
|
else
|
|
valid = FALSE;
|
|
break;
|
|
|
|
case TAG_PARITY:
|
|
if (PARITY_0 == tags[i].ti_Data ||
|
|
PARITY_1 == tags[i].ti_Data ||
|
|
PARITY_EVEN == tags[i].ti_Data ||
|
|
PARITY_ODD == tags[i].ti_Data)
|
|
{
|
|
data->parity = TRUE;
|
|
data->paritytype = tags[i].ti_Data;
|
|
}
|
|
else
|
|
valid = FALSE;
|
|
break;
|
|
|
|
case TAG_PARITY_OFF:
|
|
data->parity = FALSE;
|
|
break;
|
|
|
|
case TAG_SET_MCR:
|
|
serial_outp(data, UART_MCR, (tags[i].ti_Data & 0x0f) | 0x08);
|
|
break;
|
|
|
|
case TAG_SKIP:
|
|
case TAG_IGNORE:
|
|
break;
|
|
|
|
default:
|
|
valid = FALSE;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
if (TRUE == valid)
|
|
serial_outp(data, UART_LCR, get_lcr(data));
|
|
|
|
return valid;
|
|
}
|
|
|
|
/******* SerialUnit::SendBreak() **********************************/
|
|
BYTE PPC4xxSerUnit__Hidd_SerialUnit__SendBreak(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_SendBreak *msg)
|
|
{
|
|
return SerErr_LineErr;
|
|
}
|
|
|
|
/******* SerialUnit::Start() **********************************/
|
|
VOID PPC4xxSerUnit__Hidd_SerialUnit__Start(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_Start *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
|
|
/*
|
|
* Allow or start feeding the UART with data. Get the data
|
|
* from upper layer.
|
|
*/
|
|
if (TRUE == data->stopped) {
|
|
if (NULL != data->DataWriteCallBack)
|
|
data->DataWriteCallBack(data->unitnum, data->DataWriteUserData);
|
|
/*
|
|
* Also mark the stopped flag as FALSE.
|
|
*/
|
|
data->stopped = FALSE;
|
|
}
|
|
}
|
|
|
|
/******* SerialUnit::Stop() **********************************/
|
|
VOID PPC4xxSerUnit__Hidd_SerialUnit__Stop(OOP_Class *cl, OOP_Object *o, struct pHidd_SerialUnit_Stop *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
|
|
/*
|
|
* The next time the interrupt comes along and asks for
|
|
* more data we just don't do anything...
|
|
*/
|
|
data->stopped = TRUE;
|
|
}
|
|
|
|
/****** SerialUnit::GetCapabilities ********************************/
|
|
VOID PPC4xxSerUnit__Hidd_SerialUnit__GetCapabilities(OOP_Class * cl, OOP_Object *o, struct TagItem * tags)
|
|
{
|
|
if (NULL != tags)
|
|
{
|
|
int i = 0;
|
|
BOOL end = FALSE;
|
|
while (FALSE == end)
|
|
{
|
|
switch (tags[i].ti_Tag)
|
|
{
|
|
case HIDDA_SerialUnit_BPSRate:
|
|
tags[i].ti_Data = (STACKIPTR)valid_baudrates;
|
|
break;
|
|
|
|
case HIDDA_SerialUnit_DataLength:
|
|
tags[i].ti_Data = (STACKIPTR)valid_datalengths;
|
|
break;
|
|
|
|
case TAG_DONE:
|
|
end = TRUE;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/****** SerialUnit::GetStatus ********************************/
|
|
UWORD PPC4xxSerUnit__Hidd_SerialUnit__GetStatus(OOP_Class * cl, OOP_Object *o, struct pHidd_SerialUnit_GetStatus *msg)
|
|
{
|
|
struct HIDDSerialUnitData * data = OOP_INST_DATA(cl, o);
|
|
UWORD status = 0;
|
|
UBYTE msr = serial_inp(data, UART_MSR);
|
|
UBYTE mcr = serial_inp(data, UART_MCR);
|
|
|
|
if (msr & UART_MSR_DCD)
|
|
status |= (1<<5);
|
|
if (msr & UART_MSR_DSR)
|
|
status |= (1<<3);
|
|
if (msr & UART_MSR_CTS)
|
|
status |= (1<<4);
|
|
|
|
if (mcr & UART_MCR_DTR)
|
|
status |= (1<<7);
|
|
if (mcr & UART_MCR_RTS)
|
|
status |= (1<<6); /* old RKMs say 'ready to send' */
|
|
return status;
|
|
}
|
|
|
|
/************* The software interrupt handler that gets data from UART *****/
|
|
|
|
|
|
#define READBUFFER_SIZE 513
|
|
|
|
static AROS_UFH3(void, serialunit_receive_data,
|
|
AROS_UFHA(APTR, iD, A1),
|
|
AROS_UFHA(APTR, iC, A5),
|
|
AROS_UFHA(struct ExecBase *, SysBase, A6))
|
|
{
|
|
AROS_USERFUNC_INIT
|
|
|
|
struct HIDDSerialUnitData * data = iD;
|
|
int len = 0;
|
|
UBYTE buffer[READBUFFER_SIZE];
|
|
|
|
/*
|
|
** Read the data from the port ...
|
|
*/
|
|
do
|
|
{
|
|
buffer[len++] = serial_inp(data, UART_RX);
|
|
}
|
|
while (serial_inp(data, UART_LSR) & UART_LSR_DR);
|
|
|
|
/*
|
|
** ... and deliver them to whoever is interested.
|
|
*/
|
|
|
|
if (NULL != data->DataReceivedCallBack)
|
|
data->DataReceivedCallBack(buffer, len, data->unitnum, data->DataReceivedUserData);
|
|
|
|
return;
|
|
|
|
AROS_USERFUNC_EXIT
|
|
}
|
|
|
|
AROS_UFH3(ULONG, serialunit_write_more_data,
|
|
AROS_UFHA(APTR, iD, A1),
|
|
AROS_UFHA(APTR, iC, A5),
|
|
AROS_UFHA(struct ExecBase *, SysBase, A6))
|
|
{
|
|
AROS_USERFUNC_INIT
|
|
|
|
ULONG bytes = 0;
|
|
struct HIDDSerialUnitData * data = iD;
|
|
|
|
/*
|
|
* If the output is currently stopped just don't do
|
|
* anything here.
|
|
*/
|
|
if (TRUE == data->stopped)
|
|
return 0;
|
|
|
|
/*
|
|
** Ask for more data be written to the unit
|
|
*/
|
|
D(bug("Asking for more data to be written to unit %d\n",data->unitnum));
|
|
|
|
if (NULL != data->DataWriteCallBack)
|
|
bytes = data->DataWriteCallBack(data->unitnum, data->DataWriteUserData);
|
|
return bytes;
|
|
|
|
AROS_USERFUNC_EXIT
|
|
}
|
|
|
|
|
|
/* some help routines */
|
|
|
|
unsigned char get_lcr(struct HIDDSerialUnitData * data)
|
|
{
|
|
char lcr;
|
|
switch (data->datalength)
|
|
{
|
|
case 5: lcr = 0;
|
|
break;
|
|
|
|
case 6: lcr = 1;
|
|
break;
|
|
|
|
case 7: lcr = 2;
|
|
break;
|
|
|
|
case 8: lcr = 3;
|
|
break;
|
|
|
|
default: lcr = 3;
|
|
}
|
|
|
|
switch (data->stopbits)
|
|
{
|
|
case 1: /* 1 stopbit */
|
|
/* nothing to do */
|
|
break;
|
|
|
|
case 3: /* 1.5 stopbits (is this supported ?!!!) */
|
|
if (data->datalength == 5)
|
|
lcr |= (1 << 2);
|
|
break;
|
|
|
|
case 2: /* 2 stopbits */
|
|
if (data->datalength >= 6 && data->datalength <= 8)
|
|
lcr |= (1 << 2);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (TRUE == data->parity)
|
|
{
|
|
lcr |= (1 << 3);
|
|
|
|
switch (data->paritytype)
|
|
{
|
|
case PARITY_EVEN:
|
|
lcr |= (1 << 4);
|
|
break;
|
|
|
|
case PARITY_1:
|
|
lcr |= (1 << 5);
|
|
break;
|
|
|
|
case PARITY_0:
|
|
lcr |= (1 << 4) | (1 << 5);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
if (TRUE == data->breakcontrol)
|
|
lcr |= (1 << 6);
|
|
return lcr;
|
|
}
|
|
|
|
unsigned char get_fcr(ULONG baudrate)
|
|
{
|
|
unsigned char fcr;
|
|
fcr = (1 << 0);
|
|
|
|
/*
|
|
Depending on the baudrate set the fifo interrupt threshold to a
|
|
different value.
|
|
*/
|
|
|
|
if (baudrate < 1200)
|
|
fcr |= (3 << 6);
|
|
else
|
|
if (baudrate < 9600)
|
|
fcr |= (2 << 6);
|
|
else
|
|
if (baudrate < 38400)
|
|
fcr |= (1 << 6);
|
|
|
|
return fcr;
|
|
}
|
|
|
|
BOOL set_baudrate(struct HIDDSerialUnitData * data, ULONG speed)
|
|
{
|
|
int quot;
|
|
|
|
if (!(speed >= 50 && speed <= 115200))
|
|
return FALSE;
|
|
|
|
quot = CRYSTAL_SPEED / (speed << 4);
|
|
|
|
/* set the speed on the UART now */
|
|
serial_outp(data, UART_LCR, get_lcr(data) | UART_LCR_DLAB);
|
|
serial_outp(data, UART_DLL, quot & 0xff);
|
|
serial_outp(data, UART_DLM, quot >> 8);
|
|
serial_outp(data, UART_LCR, get_lcr(data));
|
|
serial_outp(data, UART_FCR, get_fcr(speed) | UART_FCR_ENABLE_FIFO);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* Serial interrupts */
|
|
|
|
void serial_int(void *data, void *data2);
|
|
{
|
|
struct HIDDSerialUnitData *unit = data;
|
|
|
|
if (unit)
|
|
code = serial_inp(unit, UART_IIR) & 0x07;
|
|
|
|
switch (code)
|
|
{
|
|
case UART_IIR_RLSI:
|
|
(void)serial_inp(unit, UART_LSR);
|
|
break;
|
|
|
|
case UART_IIR_RDI:
|
|
if (unit) {
|
|
AROS_UFC3(void, serialunit_receive_data,
|
|
AROS_UFCA(APTR , unit, A1),
|
|
AROS_UFCA(APTR , NULL , A5),
|
|
AROS_UFCA(struct ExecBase * , SysBase, A6));
|
|
}
|
|
break;
|
|
|
|
case UART_IIR_MSI:
|
|
(void)serial_inp(unit, UART_MSR);
|
|
break;
|
|
|
|
case UART_IIR_THRI:
|
|
if (unit)
|
|
if (0 == serialunit_write_more_data(unit, NULL, SysBase))
|
|
(void)serial_inp(unit, UART_IIR);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void adapt_data(struct HIDDSerialUnitData * data,
|
|
struct Preferences * prefs)
|
|
{
|
|
/*
|
|
* Parity.
|
|
*/
|
|
data->parity = TRUE;
|
|
|
|
switch ((prefs->SerParShk >> 4) & 0x0f) {
|
|
|
|
case SPARITY_NONE:
|
|
default: /* DEFAULT !! */
|
|
data->parity = FALSE;
|
|
break;
|
|
|
|
case SPARITY_EVEN:
|
|
data->paritytype = PARITY_EVEN;
|
|
break;
|
|
|
|
case SPARITY_ODD:
|
|
data->paritytype = PARITY_ODD;
|
|
break;
|
|
|
|
case SPARITY_MARK:
|
|
data->paritytype = PARITY_1;
|
|
break;
|
|
case SPARITY_SPACE:
|
|
data->paritytype = PARITY_0;
|
|
break;
|
|
|
|
}
|
|
|
|
/*
|
|
* Bit per character
|
|
*/
|
|
switch ((prefs->SerRWBits & 0x0f)) {
|
|
default: /* 8 bit */
|
|
case 0:
|
|
data->datalength = 8;
|
|
break;
|
|
|
|
case 1: /* 7 bit */
|
|
data->datalength = 7;
|
|
break;
|
|
|
|
case 2: /* 6 bit */
|
|
data->datalength = 6;
|
|
break;
|
|
|
|
case 3: /* 5 bit */
|
|
data->datalength = 5;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* 2 stop bits ? default is '1'.
|
|
*/
|
|
if (1 == (prefs->SerStopBuf >> 4))
|
|
data->stopbits = 2;
|
|
else
|
|
data->stopbits = 1;
|
|
|
|
/*
|
|
* Handshake to be used.
|
|
*/
|
|
// MISSING!
|
|
}
|