📄 comclass.cpp
字号:
#include "sc_cfg.h"
#include "common.h"
#include "class.h"
#include "extern.h"
rxring_t inring[MAX_PORT];
txring_t outring[MAX_PORT];
INT32U rx_count[MAX_PORT];
INT32U tx_count[MAX_PORT];
void interrupt (*Moxa1OldHand)(...);
void interrupt (*Moxa2OldHand)(...);
void interrupt Moxa1int(...);
void interrupt Moxa2int(...);
// set sio parameter
void ComParaSet(INT16U addr, INT16U baud, INT8U databit, INT8U stopbit, INT8U parity);
// write rece sio data to buffer
void com_to_buf(INT8U data, INT8U portno);
// get rece buffer bytes
INT16U get_com_rece_num(INT8U portno);
// get nbytes from rece buffer not delete
INT16U get_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno);
// get nbytes from rece buf & delete
INT16U read_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno);
// delete one byte from rece buffer
void del_com_rece_one(INT8U portno);
// initial moxa card (1) reset moxa card (1)
void InitMoxa1(void);
void ResetMoxa1(void);
// initial moxa card (2) reset moxa card (2)
void InitMoxa2(void);
void ResetMoxa2(void);
// call bufinit() & set addr & set intno
void CommInit(void);
// write len bytes data to send buffer & sending
void com_transfer(INT8U portno, INT16U len, INT8U *buf);
// check port busy & not busy sending
BOOLEAN port_free(INT8U portno);
void ComParaSet(INT16U addr, INT16U baud,
INT8U databit, INT8U stopbit, INT8U parity)
{
INT16U divisor;
INT8U parmbyte;
divisor = 115200L / baud;
outp(addr + 3, 0x80);//enable
outp(addr, (INT8U)(divisor & 0xff));
outp(addr + 1, (INT8U)(divisor >> 8));
parmbyte = databit - 5;
if (stopbit == 2) parmbyte |= 0x04;
if (parity != 0) parmbyte |= 0x08; //none
if (parity == 1) parmbyte |= 0x10; //even;
outportb(addr + 3, parmbyte);
}
void com_to_buf(INT8U data, INT8U portno)
{
if (inring[portno].count < inring[portno].size) {
inring[portno].count++;
rx_count[portno]++;
inring[portno].buf[inring[portno].next] = data;
if (++inring[portno].next >= inring[portno].size)
inring[portno].next = 0;
}
else {
if (++inring[portno].start >= inring[portno].size)
inring[portno].start = 0;
rx_count[portno]++;
inring[portno].buf[inring[portno].next] = data;
if (++inring[portno].next >= inring[portno].size)
inring[portno].next = 0;
}
}
INT16U get_com_rece_num(INT8U portno)
{
INT16U count;
OS_ENTER_CRITICAL();
count = inring[portno].count;
OS_EXIT_CRITICAL();
return(count);
}
INT16U get_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno)
{
int need_to_get;
int count, start, size;
int i;
OS_ENTER_CRITICAL();
count = inring[portno].count;
start = inring[portno].start;
size = inring[portno].size;
OS_EXIT_CRITICAL();
if (count >= len) need_to_get = len;
else need_to_get = count;
for (i = 0; i < need_to_get; i++) {
buf[i] = inring[portno].buf[start];
if (count > 0) {
count--;
start++;
if (start >= size) start = 0;
}
}
return (need_to_get);
}
INT16U read_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno)
{
INT16U need_to_get;
int i;
OS_ENTER_CRITICAL();
if (inring[portno].count >= len) need_to_get = len;
else need_to_get = inring[portno].count;
for (i = 0; i < need_to_get; i++) {
buf[i] = inring[portno].buf[inring[portno].start];
if (inring[portno].count > 0) {
inring[portno].start++;
if (inring[portno].start >= inring[portno].size)
inring[portno].start = 0;
}
}
inring[portno].count -= need_to_get;
OS_EXIT_CRITICAL();
return (need_to_get);
}
void del_com_rece_one(INT8U portno)
{
OS_ENTER_CRITICAL();
if (inring[portno].count > 0) {
inring[portno].count--;
inring[portno].start++;
if (inring[portno].start >= inring[portno].size)
inring[portno].start = 0;
}
OS_EXIT_CRITICAL();
}
void clear_com_rece_buf(INT8U portno)
{
OS_ENTER_CRITICAL();
inring[portno].count = 0;
inring[portno].start = 0;
inring[portno].next = 0;
inring[portno].size = RX_COM_BUF_SIZE;
OS_EXIT_CRITICAL();
}
void interrupt Moxa1int(...)
{
int i;
disable();
for (i = 0; i < _sio1total; i++) {
if (!PortSet[i].isReady || !PortSet[i].isWork)
continue;
while (inp(PortSet[i].BaseAddr + 0x05) & 0x01)
com_to_buf(inp(PortSet[i].BaseAddr), i);
}
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void interrupt Moxa2int(...)
{
int i;
disable();
for (i = _sio1total; i < _sio1total + _sio2total; i++) {
if (!PortSet[i].isReady || !PortSet[i].isWork)
continue;
while (inp(PortSet[i].BaseAddr + 0x05) & 0x01)
com_to_buf(inp(PortSet[i].BaseAddr), i);
}
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void InitMoxa1()
{
INT8U oldval, picmask;
INT16U i;
if (_sio1int < 8 || _sio1int > 15) {
perror("comm board1 interrupt error");
exit(0);
}
if ((~CardStatusYx) & 1) return;
disable();
Moxa1OldHand = getvect(_sio1int + 0x68);
setvect(_sio1int + 0x68, Moxa1int);
for (i = 0; i < _sio1total; i++) {
if (!PortSet[i].isReady || !PortSet[i].isWork)
continue;
outp(PortSet[i].BaseAddr + 0x04, 0x0f); // modem control register
inp(PortSet[i].BaseAddr + 0x05);
inp(PortSet[i].BaseAddr + 0x06);
inp(PortSet[i].BaseAddr);
inp(PortSet[i].BaseAddr + 0x02);
outp(PortSet[i].BaseAddr + 0x02, 0xc7); // rx trigger level 14byte in FIFO
outp(PortSet[i].BaseAddr + 0x01, 0x01); // enable interrupts on the UART
ComParaSet(PortSet[i].BaseAddr, PortSet[i].Baud,
PortSet[i].DataBit, PortSet[i].StopBit, PortSet[i].Parity);
}
picmask = 1 << (_sio1int % 8);
oldval = inp(0x21);
outp(0x21, oldval & 0xfb);
oldval = inp(0xa1);
outp(0xa1, oldval & ~picmask);
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void ResetMoxa1(void)
{
INT8U oldval, picmask;
if ((~CardStatusYx) & 1) return;
disable();
setvect(_sio1int + 0x68, Moxa1OldHand);
picmask = 1 << (_sio1int % 8);
oldval = inp(0xa1);
outp(0xa1, oldval | picmask);
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void InitMoxa2(void)
{
INT8U oldval, picmask;
INT16U i;
if (_sio2int < 8 || _sio2int > 15) {
perror("comm board2 interrupt error");
exit(0);
}
if ((~CardStatusYx) & 2) return;
disable();
Moxa2OldHand = getvect(_sio2int + 0x68);
setvect(_sio2int + 0x68, Moxa2int);
for (i = _sio1total; i < _sio1total + _sio2total; i++) {
if (!PortSet[i].isReady || !PortSet[i].isWork)
continue;
outp(PortSet[i].BaseAddr + 0x04, 0x0f); // modem control register
inp(PortSet[i].BaseAddr + 0x05);
inp(PortSet[i].BaseAddr + 0x06);
inp(PortSet[i].BaseAddr);
inp(PortSet[i].BaseAddr + 0x02);
outp(PortSet[i].BaseAddr + 0x02, 0xc7); // rx trigger level 14byte in FIFO
outp(PortSet[i].BaseAddr + 0x01, 0x01); // enable interrupts on the UART
ComParaSet(PortSet[i].BaseAddr, PortSet[i].Baud,
PortSet[i].DataBit, PortSet[i].StopBit, PortSet[i].Parity);
}
picmask = 1 << (_sio2int % 8);
oldval = inp(0x21);
outp(0x21, oldval & 0xfb);
oldval = inp(0xa1);
outp(0xa1, oldval & ~picmask);
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void ResetMoxa2(void)
{
INT8U oldval, picmask;
if ((~CardStatusYx) & 2) return; // sio2 not exist
disable();
setvect(_sio2int + 0x68, Moxa2OldHand);
picmask = 1 << (_sio2int % 8);
oldval = inp(0xa1);
outp(0xa1, oldval | picmask);
outp(0x20, 0x20);
outp(0xa0, 0x20);
enable();
}
void CommInit(void)
{
int i, j;
for (i = 0; i < MAX_PORT; i++) {
inring[i].count = 0;
inring[i].start = 0;
inring[i].next = 0;
inring[i].size = RX_COM_BUF_SIZE;
outring[i].count = 0;
outring[i].curptr = 0;
outring[i].size = TX_COM_BUF_SIZE;
outring[i].flaguse = FALSE;
rx_count[i] = 0;
tx_count[i] = 0;
}
for (i = 0; i < _sio1total; i++)
PortSet[i].BaseAddr = _sio1base + i * 8;
for (j = 0; j < _sio2total; j++)
PortSet[i + j].BaseAddr = _sio2base + j * 8;
}
BOOLEAN port_free(INT8U portno)
{
int i;
if (inp(PortSet[portno].BaseAddr + 5) & 0x20) {
if (outring[portno].flaguse == TRUE) {
if ((outring[portno].count - outring[portno].curptr) < 12) {
while (outring[portno].curptr < outring[portno].count) {
outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
outring[portno].curptr++;
tx_count[portno]++;
}
outring[portno].flaguse = FALSE;
}
else {
for (i = 0; i < 12; i++) {
outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
outring[portno].curptr++;
tx_count[portno]++;
}
}
return (FALSE);
}
else return (TRUE);
}
else return (FALSE);
}
void com_transfer(INT8U portno, INT16U len, INT8U *buf)
{
int i;
if (outring[portno].flaguse == TRUE) return;
else {
if (len > outring[portno].size) return;
memcpy(outring[portno].buf, buf, len);
outring[portno].count = len;
outring[portno].curptr = 0;
outring[portno].flaguse = TRUE;
if (outring[portno].count <= 12) {
for (i = 0; i < outring[portno].count; i++) {
outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
outring[portno].curptr++;
tx_count[portno]++;
}
outring[portno].flaguse = FALSE;
}
else {
for (i = 0; i< 12; i++) {
outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
outring[portno].curptr++;
tx_count[portno]++;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -