/* * Copyright (c) 2001 Tommy Bohlin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* actisys.c */ #include /********************************************************************** * Constants **********************************************************************/ static const char id_actisys[]="actisys"; /********************************************************************** * Data structures **********************************************************************/ typedef struct Actisys { SerialDevice sd; SerialPort* sp; bool plus; bool initial; int pulses; int state; } Actisys; /********************************************************************** * Actisys control **********************************************************************/ static void speedTimer(void* sd) { Actisys* act=(Actisys*)sd; SerialPort* sp=act->sp; switch(act->state) { case 1: sp->setLine(sp,LINE_RTS); act->initial=FALSE; act->state=2; evtSetTimer(1,speedTimer,act); /* At least 2us */ break; case 2: sp->setLine(sp,LINE_DTR|LINE_RTS); if(act->pulses-->0) { act->state=3; evtSetTimer(1,speedTimer,act); /* At least 2us */ } else { act->state=0; } break; case 3: sp->setLine(sp,LINE_DTR); act->state=2; evtSetTimer(1,speedTimer,act); /* At least 2us */ break; } } /********************************************************************** * Methods **********************************************************************/ static int actSetSpeed(SerialDevice* sd, int speed) { Actisys* act=(Actisys*)sd; SerialPort* sp=act->sp; sp->setSpeed(sp,speed); switch(speed) { case 19200: act->pulses=1; break; case 57600: act->pulses=2; break; case 115200: act->pulses=3; break; case 38400: act->pulses=4; break; default: /* 9600 */ act->pulses=0; break; } if(act->initial) { act->state=1; sp->setLine(sp,LINE_DTR|LINE_RTS); /* Must wait at least 50ms after initial * power on to charge internal capacitor */ evtSetTimer(50,speedTimer,act); return 80+20*act->pulses; } else { act->state=2; sp->setLine(sp,LINE_RTS); evtSetTimer(1,speedTimer,act); /* At least 2us */ return 30+20*act->pulses; } } static int actGetSpeedMask(SerialDevice* sd) { Actisys* act=(Actisys*)sd; int mask=act->sp->getSpeedMask(act->sp); mask&=SPEED_9600|SPEED_19200|SPEED_38400|SPEED_57600|SPEED_115200; if(!act->plus) mask&=~SPEED_38400; return mask; } static int actGetMinTurnaroundMask(SerialDevice* sd) { return MIN_TA_10ms|MIN_TA_5ms|MIN_TA_1ms|MIN_TA_500us| MIN_TA_100us|MIN_TA_50us|MIN_TA_10us; } static int actGetChar(SerialDevice* sd) { Actisys* act=(Actisys*)sd; return act->sp->getChar(act->sp); } static void actPutChar(SerialDevice* sd, int c) { Actisys* act=(Actisys*)sd; if(act->state==0) act->sp->putChar(act->sp,c); } static void actClose(SerialDevice* sd) { Actisys* act=(Actisys*)sd; SerialPort* sp=act->sp; evtCancelTimer(speedTimer,act); sp->setLine(sp,0); sp->handle=0; sp->status=0; freeMem(act); } static void actStatus(SerialPort* sp, int event) { Actisys* act=(Actisys*)sp->handle; if(act->sd.status) act->sd.status(&act->sd,event); } /********************************************************************** * External interface **********************************************************************/ SerialDevice* createACTiSYS220Device(SerialPort* sp, bool plus) { Actisys* act=allocMem(id_actisys,sizeof(Actisys)); act->sd.close=actClose; act->sd.setSpeed=actSetSpeed; act->sd.getSpeedMask=actGetSpeedMask; act->sd.getMinTurnaroundMask=actGetMinTurnaroundMask; act->sd.getChar=actGetChar; act->sd.putChar=actPutChar; act->sd.handle=0; act->sd.status=0; act->sp=sp; act->plus=plus; act->initial=TRUE; act->state=0; sp->handle=act; sp->status=actStatus; return &act->sd; }