git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2007-09-18 12:39:01 +00:00
parent 549f84d120
commit f712427135
4 changed files with 863 additions and 0 deletions

View File

@ -0,0 +1,456 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LPC214X_H_
#define _LPC214X_H_
typedef volatile unsigned char IOREG8;
typedef volatile unsigned int IOREG32;
/*
* The following values are implementation dependent. You may change them in
* order to match your HW.
*/
#define FOSC 12000000
#define CCLK 48000000
#define PCLK 12000000
/*
* System.
*/
#define MEMMAP (*((IOREG32 *)0xE01FC040))
#define PCON (*((IOREG32 *)0xE01FC0C0))
#define PCONP (*((IOREG32 *)0xE01FC0C4))
#define VPBDIV (*((IOREG32 *)0xE01FC100))
#define EXTINT (*((IOREG32 *)0xE01FC140))
#define INTWAKE (*((IOREG32 *)0xE01FC144))
#define EXTMODE (*((IOREG32 *)0xE01FC148))
#define EXTPOLAR (*((IOREG32 *)0xE01FC14C))
#define RSID (*((IOREG32 *)0xE01FC180))
#define CSPR (*((IOREG32 *)0xE01FC184))
#define SCS (*((IOREG32 *)0xE01FC1A0))
#define VPD_D4 0
#define VPD_D1 1
#define VPD_D2 2
#define VPD_RESERVED 3
#define PCTIM0 (1 << 1)
#define PCTIM1 (1 << 2)
#define PCUART0 (1 << 3)
#define PCUART1 (1 << 4)
#define PCPWM0 (1 << 5)
#define PCI2C0 (1 << 7)
#define PCSPI0 (1 << 8)
#define PCRTC (1 << 9)
#define PCSPI1 (1 << 10)
#define PCAD0 (1 << 12)
#define PCI2C1 (1 << 19)
#define PCAD1 (1 << 20)
#define PCUSB (1 << 31)
#define PCALL (PCTIM0 | PCTIM1 | PCUART0 | PCUART1 | \
PCPWM0 | PCI2C0 | PCSPI0 | PCRTC | PCSPI1 | \
PCAD0 | PCI2C1 | PCAD1 | PCUSB)
typedef struct {
IOREG32 PLL0_CON;
IOREG32 PLL0_CFG;
IOREG32 PLL0_STAT;
IOREG32 PLL0_FEED;
IOREG32 PLL1_CON;
IOREG32 PLL1_CFG;
IOREG32 PLL1_STAT;
IOREG32 PLL1_FEED;
} PLL;
#define PLLBase ((PLL *)0xE01FC080)
#define PLL0CON (PLLBase->PLL0_CON)
#define PLL0CFG (PLLBase->PLL0_CFG)
#define PLL0STAT (PLLBase->PLL0_STAT)
#define PLL0FEED (PLLBase->PLL0_FEED)
#define PLL1CON (PLLBase->PLL1_CON)
#define PLL1CFG (PLLBase->PLL1_CFG)
#define PLL1STAT (PLLBase->PLL1_STAT)
#define PLL1FEED (PLLBase->PLL1_FEED)
/*
* Pins.
*/
typedef struct {
IOREG32 PS_SEL0;
IOREG32 PS_SEL1;
IOREG32 PS_SEL2;
} PS;
#define PSBase ((PS *)0xE002C000)
#define PINSEL0 (PSBase->PS_SEL0)
#define PINSEL1 (PSBase->PS_SEL1)
#define PINSEL2 (PSBase->PS_SEL2)
/*
* VIC
*/
#define SOURCE_WDT 0
#define SOURCE_ARMCore0 2
#define SOURCE_ARMCore1 3
#define SOURCE_Timer0 4
#define SOURCE_Timer1 5
#define SOURCE_UART0 6
#define SOURCE_UART1 7
#define SOURCE_PWM0 8
#define SOURCE_I2C0 9
#define SOURCE_SPI0 10
#define SOURCE_SPI1 11
#define SOURCE_PLL 12
#define SOURCE_RTC 13
#define SOURCE_EINT0 14
#define SOURCE_EINT1 15
#define SOURCE_EINT2 16
#define SOURCE_EINT3 17
#define SOURCE_ADC0 18
#define SOURCE_I2C1 19
#define SOURCE_BOD 20
#define SOURCE_ADC1 21
#define SOURCE_USB 22
#define INTMASK(n) (1 << (n))
typedef struct {
IOREG32 VIC_IRQStatus;
IOREG32 VIC_FIQStatus;
IOREG32 VIC_RawIntr;
IOREG32 VIC_IntSelect;
IOREG32 VIC_IntEnable;
IOREG32 VIC_IntEnClear;
IOREG32 VIC_SoftInt;
IOREG32 VIC_SoftIntClear;
IOREG32 VIC_Protection;
IOREG32 unused1[3];
IOREG32 VIC_VectAddr;
IOREG32 VIC_DefVectAddr;
IOREG32 unused2[50];
IOREG32 VIC_VectAddrs[16];
IOREG32 unused3[48];
IOREG32 VIC_VectCntls[16];
} VIC;
#define VICBase ((VIC *)0xFFFFF000)
#define VICVectorsBase ((IOREG32 *)0xFFFFF100)
#define VICControlsBase ((IOREG32 *)0xFFFFF200)
#define VICIRQStatus (VICBase->VIC_IRQStatus)
#define VICFIQStatus (VICBase->VIC_FIQStatus)
#define VICRawIntr (VICBase->VIC_RawIntr)
#define VICIntSelect (VICBase->VIC_IntSelect)
#define VICIntEnable (VICBase->VIC_IntEnable)
#define VICIntEnClear (VICBase->VIC_IntEnClear)
#define VICSoftInt (VICBase->VIC_SoftInt)
#define VICSoftIntClear (VICBase->VIC_SoftIntClear)
#define VICProtection (VICBase->VIC_Protection)
#define VICVectAddr (VICBase->VIC_VectAddr)
#define VICDefVectAddr (VICBase->VIC_DefVectAddr)
#define VICVectAddrs(n) (VICBase->VIC_VectAddrs[n])
#define VICVectCntls(n) (VICBase->VIC_VectCntls[n])
/*
* MAM.
*/
typedef struct {
IOREG32 MAM_Control;
IOREG32 MAM_Timing;
} MAM;
#define MAMBase ((MAM *)0xE01FC000)
#define MAMCR (MAMBase->MAM_Control)
#define MAMTIM (MAMBase->MAM_Timing)
/*
* GPIO - FIO.
*/
typedef struct {
IOREG32 IO_PIN;
IOREG32 IO_SET;
IOREG32 IO_DIR;
IOREG32 IO_CLR;
} GPIO;
#define GPIO0Base ((GPIO *)0xE0028000)
#define IO0PIN (GPIO0Base->IO_PIN)
#define IO0SET (GPIO0Base->IO_SET)
#define IO0DIR (GPIO0Base->IO_DIR)
#define IO0CLR (GPIO0Base->IO_CLR)
#define GPIO1Base ((GPIO *)0xE0028010)
#define IO1PIN (GPIO1Base->IO_PIN)
#define IO1SET (GPIO1Base->IO_SET)
#define IO1DIR (GPIO1Base->IO_DIR)
#define IO1CLR (GPIO1Base->IO_CLR)
typedef struct {
IOREG32 FIO_DIR;
IOREG32 unused1;
IOREG32 unused2;
IOREG32 unused3;
IOREG32 FIO_MASK;
IOREG32 FIO_PIN;
IOREG32 FIO_SET;
IOREG32 FIO_CLR;
} FIO;
#define FIO0Base ((FIO *)0x3FFFC000)
#define FIO0DIR (FIO0Base->FIO_DIR)
#define FIO0MASK (FIO0Base->FIO_MASK)
#define FIO0PIN (FIO0Base->FIO_PIN)
#define FIO0SET (FIO0Base->FIO_SET)
#define FIO0CLR (FIO0Base->FIO_CLR)
#define FIO1Base ((FIO *)0x3FFFC020)
#define FIO1DIR (FIO1Base->FIO_DIR)
#define FIO1MASK (FIO1Base->FIO_MASK)
#define FIO1PIN (FIO1Base->FIO_PIN)
#define FIO1SET (FIO1Base->FIO_SET)
#define FIO1CLR (FIO1Base->FIO_CLR)
/*
* UART.
*/
typedef struct {
union {
IOREG32 UART_RBR;
IOREG32 UART_THR;
IOREG32 UART_DLL;
};
union {
IOREG32 UART_IER;
IOREG32 UART_DLM;
};
union {
IOREG32 UART_IIR;
IOREG32 UART_FCR;
};
IOREG32 UART_LCR;
IOREG32 UART_MCR; // UART1 only
IOREG32 UART_LSR;
IOREG32 unused18;
IOREG32 UART_SCR;
IOREG32 UART_ACR;
IOREG32 unused24;
IOREG32 UART_FDR;
IOREG32 unused2C;
IOREG32 UART_TER;
} UART;
/*typedef struct {
union {
IOREG8 UART_RBR;
IOREG8 UART_THR;
IOREG8 UART_DLL;
IOREG8 f1[4];
};
union {
IOREG8 UART_IER;
IOREG8 UART_DLM;
IOREG8 f2[4];
};
union {
IOREG8 UART_IIR;
IOREG8 UART_FCR;
IOREG8 f3[4];
};
IOREG8 UART_LCR;
IOREG8 f4[3];
IOREG8 UART_MCR; // UART1 only
IOREG8 f5[3];
IOREG8 UART_LSR;
IOREG8 f6[3];
IOREG32 unused18;
IOREG8 UART_SCR;
IOREG8 f7[3];
IOREG8 UART_ACR;
IOREG8 f8[3];
IOREG32 unused24;
IOREG8 UART_FDR;
IOREG8 f9[3];
IOREG32 unused2C;
IOREG8 UART_TER;
IOREG8 f10[3];
} UART;*/
#define U0Base ((UART *)0xE000C000)
#define U0RBR (U0Base->UART_RBR)
#define U0THR (U0Base->UART_THR)
#define U0DLL (U0Base->UART_DLL)
#define U0IER (U0Base->UART_IER)
#define U0DLM (U0Base->UART_DLM)
#define U0IIR (U0Base->UART_IIR)
#define U0FCR (U0Base->UART_FCR)
#define U0LCR (U0Base->UART_LCR)
#define U0LSR (U0Base->UART_LSR)
#define U0SCR (U0Base->UART_SCR)
#define U0ACR (U0Base->UART_ACR)
#define U0FDR (U0Base->UART_FDR)
#define U0TER (U0Base->UART_TER)
#define U1Base ((UART *)0xE0010000)
#define U1RBR (U1Base->UART_RBR)
#define U1THR (U1Base->UART_THR)
#define U1DLL (U1Base->UART_DLL)
#define U1IER (U1Base->UART_IER)
#define U1DLM (U1Base->UART_DLM)
#define U1IIR (U1Base->UART_IIR)
#define U1FCR (U1Base->UART_FCR)
#define U1MCR (U1Base->UART_MCR)
#define U1LCR (U1Base->UART_LCR)
#define U1LSR (U1Base->UART_LSR)
#define U1SCR (U1Base->UART_SCR)
#define U1ACR (U1Base->UART_ACR)
#define U1FDR (U1Base->UART_FDR)
#define U1TER (U1Base->UART_TER)
#define IIR_SRC_MASK 0x0F
#define IIR_SRC_NONE 0x01
#define IIR_SRC_TX 0x02
#define IIR_SRC_RX 0x04
#define IIR_SRC_ERROR 0x06
#define IIR_SRC_TIMEOUT 0x0C
#define IER_RBR 1
#define IER_THRE 2
#define IER_STATUS 4
#define IIR_INT_PENDING 1
#define LCR_WL5 0
#define LCR_WL6 1
#define LCR_WL7 2
#define LCR_WL8 3
#define LCR_STOP1 0
#define LCR_STOP2 4
#define LCR_NOPARITY 0
#define LCR_PARITYODD 0x08
#define LCR_PARITYEVEN 0x18
#define LCR_PARITYONE 0x28
#define LCR_PARITYZERO 0x38
#define LCR_BREAK_ON 0x40
#define LCR_DLAB 0x80
#define FCR_ENABLE 1
#define FCR_RXRESET 2
#define FCR_TXRESET 4
#define FCR_TRIGGER0 0
#define FCR_TRIGGER1 0x40
#define FCR_TRIGGER2 0x80
#define FCR_TRIGGER3 0xC0
#define LSR_RBR_FULL 1
#define LSR_OVERRUN 2
#define LSR_PARITY 4
#define LSR_FRAMING 8
#define LSR_BREAK 0x10
#define LSR_THRE 0x20
#define LSR_TEMT 0x40
#define LSR_RXFE 0x80
#define TER_ENABLE 0x80
/*
* Timers/Counters.
*/
typedef struct {
IOREG32 TC_IR;
IOREG32 TC_TCR;
IOREG32 TC_TC;
IOREG32 TC_PR;
IOREG32 TC_PC;
IOREG32 TC_MCR;
IOREG32 TC_MR0;
IOREG32 TC_MR1;
IOREG32 TC_MR2;
IOREG32 TC_MR3;
IOREG32 TC_CCR;
IOREG32 TC_CR0;
IOREG32 TC_CR1;
IOREG32 TC_CR2;
IOREG32 TC_CR3;
IOREG32 TC_EMR;
IOREG32 TC_CTCR;
} TC;
#define T0Base ((TC *)0xE0004000)
#define T0IR (T0Base->TC_IR)
#define T0TCR (T0Base->TC_TCR)
#define T0TC (T0Base->TC_TC)
#define T0PR (T0Base->TC_PR)
#define T0PC (T0Base->TC_PC)
#define T0MCR (T0Base->TC_MCR)
#define T0MR0 (T0Base->TC_MR0)
#define T0MR1 (T0Base->TC_MR1)
#define T0MR2 (T0Base->TC_MR2)
#define T0MR3 (T0Base->TC_MR3)
#define T0CCR (T0Base->TC_CCR)
#define T0CR0 (T0Base->TC_CR0)
#define T0CR1 (T0Base->TC_CR1)
#define T0CR2 (T0Base->TC_CR2)
#define T0CR3 (T0Base->TC_CR3)
#define T0EMR (T0Base->TC_EMR)
#define T0CTCR (T0Base->TC_CTCR)
#define T1Base ((TC *)0xE0008000)
#define T1IR (T1Base->TC_IR)
#define T1TCR (T1Base->TC_TCR)
#define T1TC (T1Base->TC_TC)
#define T1PR (T1Base->TC_PR)
#define T1PC (T1Base->TC_PC)
#define T1MCR (T1Base->TC_MCR)
#define T1MR0 (T1Base->TC_MR0)
#define T1MR1 (T1Base->TC_MR1)
#define T1MR2 (T1Base->TC_MR2)
#define T1MR3 (T1Base->TC_MR3)
#define T1CCR (T1Base->TC_CCR)
#define T1CR0 (T1Base->TC_CR0)
#define T1CR1 (T1Base->TC_CR1)
#define T1CR2 (T1Base->TC_CR2)
#define T1CR3 (T1Base->TC_CR3)
#define T1EMR (T1Base->TC_EMR)
#define T1CTCR (T1Base->TC_CTCR)
/*
* Watchdog.
*/
typedef struct {
IOREG32 WD_MOD;
IOREG32 WD_TC;
IOREG32 WD_FEED;
IOREG32 WD_TV;
} WD;
#define WDBase ((WD *)0xE0000000)
#define WDMOD (WDBase->WD_MOD)
#define WDTC (WDBase->WD_TC)
#define WDFEED (WDBase->WD_FEED)
#define WDTV (WDBase->WD_TV)
/*
* DAC.
*/
#define DACR (*((IOREG32 *)0xE006C000))
#endif /* _LPC214X_H_ */

View File

@ -0,0 +1,150 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ch.h>
#include "lpc214x.h"
#include "lpc214x_serial.h"
#define SERIAL_BUFFERS_SIZE 128
FullDuplexDriver COM1;
BYTE8 ib1[SERIAL_BUFFERS_SIZE];
BYTE8 ob1[SERIAL_BUFFERS_SIZE];
FullDuplexDriver COM2;
BYTE8 ib2[SERIAL_BUFFERS_SIZE];
BYTE8 ob2[SERIAL_BUFFERS_SIZE];
static void SetError(IOREG32 err, FullDuplexDriver *com) {
UWORD16 sts = 0;
if (err & LSR_OVERRUN)
sts |= SD_OVERRUN_ERROR;
if (err & LSR_PARITY)
sts |= SD_PARITY_ERROR;
if (err & LSR_FRAMING)
sts |= SD_FRAMING_ERROR;
if (err & LSR_BREAK)
sts |= SD_BREAK_DETECTED;
chFDDAddFlagsI(com, sts);
}
/*
* Tries hard to clear all the pending interrupt sources, we dont want to
* go through the whole ISR and have another interrupt soon after.
*/
static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
while (TRUE) {
switch (u->UART_IIR & IIR_SRC_MASK) {
case IIR_SRC_NONE:
VICVectAddr = 0;
return;
case IIR_SRC_ERROR:
SetError(u->UART_LSR, com);
break;
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
while (u->UART_LSR & LSR_RBR_FULL)
chFDDIncomingDataI(com, u->UART_RBR);
break;
case IIR_SRC_TX:
{
t_msg b = chFDDRequestDataI(com);
if (b < Q_OK)
u->UART_IER &= ~IER_THRE;
else
u->UART_THR = b;
}
default:
u->UART_THR;
u->UART_RBR;
u->UART_IIR;
}
}
}
/*
* Invoked by the high driver when one or more bytes are inserted in the
* output queue.
*/
static void OutNotify1(void) {
UART *u = U0Base;
if (u->UART_LSR & LSR_THRE)
u->UART_THR = chOQGetI(&COM1.sd_oqueue);
u->UART_IER |= IER_THRE;
}
/*
* Invoked by the high driver when one or more bytes are inserted in the
* output queue.
*/
static void OutNotify2(void) {
UART *u = U1Base;
if (u->UART_LSR & LSR_THRE)
u->UART_THR = chOQGetI(&COM1.sd_oqueue);
u->UART_IER |= IER_THRE;
}
void UART0Irq(void){
ServeInterrupt(U0Base, &COM1);
}
void UART1Irq(void){
ServeInterrupt(U1Base, &COM2);
}
/*
* UART setup, must be invoked with interrupts disabled.
*/
void SetUARTI(UART *u, int speed, int lcr, int fcr) {
int div = PCLK / (speed << 4);
u->UART_LCR = lcr | LCR_DLAB;
u->UART_DLL = div;
u->UART_DLM = div >> 8;
u->UART_LCR = lcr;
u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | fcr;
u->UART_ACR = 0;
u->UART_FDR = 0x10;
u->UART_TER = TER_ENABLE;
u->UART_IER = IER_RBR | IER_STATUS;
}
/*
* Serial subsystem initialization.
*/
void InitSerial(void) {
PCONP = (PCONP & PCALL) | PCUART0 | PCUART1;
chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
SetUARTI(U0Base, 38400, LCR_WL8 | LCR_STOP1 | LCR_NOPARITY, FCR_TRIGGER0);
chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
SetUARTI(U1Base, 38400, LCR_WL8 | LCR_STOP1 | LCR_NOPARITY, FCR_TRIGGER0);
VICIntEnable |= INTMASK(SOURCE_UART0) | INTMASK(SOURCE_UART1);
}

View File

@ -0,0 +1,30 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LPC2000_SERIAL_H_
#define _LPC2000_SERIAL_H_
void InitSerial(void);
void SetUARTI(UART *u, int speed, int lcr, int fcr);
void UART0IrqHandler(void);
void UART1IrqHandler(void);
extern FullDuplexDriver COM1, COM2;
#endif /* _LPC2000_SERIAL_H_*/

227
ports/Win32/simcom.c Normal file
View File

@ -0,0 +1,227 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Win32 COM port simulator (on socket).
*/
#include <chconf.h>
#include <windows.h>
#include <stdio.h>
#undef CDECL
#include <ch.h>
#define COM1PORT 29001
#define COM2PORT 29002
struct simcom {
BYTE8 com_ib[1024];
BYTE8 com_ob[1024];
SOCKET com_listen;
SOCKET com_data;
};
FullDuplexDriver COM1;
static struct simcom sc1;
FullDuplexDriver COM2;
static struct simcom sc2;
static u_long nb = 1;
static void init(char *name, FullDuplexDriver *sd,
struct simcom *sc, unsigned short port) {
struct sockaddr_in sad;
struct protoent *prtp;
chFDDInit(sd,
sc->com_ib, sizeof(sc->com_ib), NULL,
sc->com_ob, sizeof(sc->com_ob), NULL);
sc->com_listen = INVALID_SOCKET;
sc->com_data = INVALID_SOCKET;
if ((prtp = getprotobyname("tcp")) == NULL) {
printf("%s: Error mapping protocol name to protocol number\n", name);
goto abort;
}
sc->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sc->com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", name);
goto abort;
}
if (ioctlsocket(sc->com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", name);
goto abort;
}
memset(&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons(port);
if (bind(sc->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", name);
goto abort;
}
if (listen(sc->com_listen, 1) != 0) {
printf("%s: Error binding socket\n", name);
goto abort;
}
printf("Full Duplex Channel %s listening on port %d\n", name, port);
return;
abort:
if (sc->com_listen != INVALID_SOCKET)
closesocket(sc->com_listen);
WSACleanup();
exit(1);
}
void InitSimCom1(void) {
init("COM1", &COM1, &sc1, COM1PORT);
}
void InitSimCom2(void) {
init("COM2", &COM2, &sc2, COM2PORT);
}
static BOOL connint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
if (sc->com_data == INVALID_SOCKET) {
struct sockaddr addr;
int addrlen = sizeof(addr);
if ((sc->com_data = accept(sc->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
return FALSE;
if (ioctlsocket(sc->com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", name);
goto abort;
}
chFDDAddFlagsI(sd, SD_CONNECTED);
return TRUE;
}
return FALSE;
abort:
if (sc->com_listen != INVALID_SOCKET)
closesocket(sc->com_listen);
if (sc->com_data != INVALID_SOCKET)
closesocket(sc->com_data);
WSACleanup();
exit(1);
}
BOOL Com1ConnInterruptSimCom(void) {
return connint("COM1", &COM1, &sc1);
}
BOOL Com2ConnInterruptSimCom(void) {
return connint("COM2", &COM2, &sc2);
}
static BOOL inint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
if (sc->com_data != INVALID_SOCKET) {
int i;
BYTE8 data[32];
/*
* Input.
*/
int n = recv(sc->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sc->com_data);
sc->com_data = INVALID_SOCKET;
chFDDAddFlagsI(sd, SD_DISCONNECTED);
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sc->com_data);
sc->com_data = INVALID_SOCKET;
return FALSE;
}
for (i = 0; i < n; i++)
chFDDIncomingDataI(sd, data[i]);
return TRUE;
}
return FALSE;
}
BOOL Com1InInterruptSimCom(void) {
return inint("COM1", &COM1, &sc1);
}
BOOL Com2InInterruptSimCom(void) {
return inint("COM2", &COM2, &sc2);
}
static BOOL outint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
if (sc->com_data != INVALID_SOCKET) {
int n;
BYTE8 data[1];
/*
* Input.
*/
n = chFDDRequestDataI(sd);
if (n < 0)
return FALSE;
data[0] = (BYTE8)n;
n = send(sc->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sc->com_data);
sc->com_data = INVALID_SOCKET;
chFDDAddFlagsI(sd, SD_DISCONNECTED);
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sc->com_data);
sc->com_data = INVALID_SOCKET;
return FALSE;
}
return TRUE;
}
return FALSE;
}
BOOL Com1OutInterruptSimCom(void) {
return outint("COM1", &COM1, &sc1);
}
BOOL Com2OutInterruptSimCom(void) {
return outint("COM2", &COM2, &sc2);
}