2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Parallel Unit hidd class implementation.
9 #define __OOP_NOATTRBASES__
11 /* the rest are Amiga includes */
12 #include <proto/exec.h>
13 #include <proto/utility.h>
14 #include <proto/oop.h>
15 #include <proto/alib.h>
16 #include <exec/libraries.h>
17 #include <exec/ports.h>
18 #include <exec/memory.h>
19 #include <exec/interrupts.h>
20 #include <exec/lists.h>
21 #include <aros/symbolsets.h>
23 #include <utility/tagitem.h>
24 #include <hidd/parallel.h>
25 #include <hidd/unixio.h>
27 #include "parallel_intern.h"
29 #include LC_LIBDEFS_FILE
35 #include <aros/debug.h>
37 void parallelunit_receive_data();
38 void parallelunit_write_more_data();
40 static inline unsigned char inb(unsigned short port
)
54 static inline void outb(unsigned char value
, unsigned short port
)
59 : "a" (value
), "Nd" (port
)
63 #define parallel_usleep(x) __asm__ __volatile__("\noutb %al,$0x80\n")
65 static inline void parallel_out(struct HIDDParallelUnitData
* data
,
69 outb(value
, data
->baseaddr
+offset
);
72 static inline unsigned int parallel_in(struct HIDDParallelUnitData
* data
,
75 return inb(data
->baseaddr
+offset
);
78 /*************************** Classes *****************************/
80 /* IO bases for every Parallel port */
82 static ULONG bases
[] = { 0x378, 0x278, 0x3bc};
84 static OOP_AttrBase HiddParallelUnitAB
;
86 static struct OOP_ABDescr attrbases
[] =
88 { IID_Hidd_ParallelUnit
, &HiddParallelUnitAB
},
92 /******* ParallelUnit::New() ***********************************/
93 OOP_Object
*PCParUnit__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
95 struct HIDDParallelUnitData
* data
;
96 // static const struct TagItem tags[] = {{ TAG_END, 0}};
97 struct TagItem
*tag
, *tstate
;
100 EnterFunc(bug("ParallelUnit::New()\n"));
102 tstate
= msg
->attrList
;
103 while ((tag
= NextTagItem(&tstate
))) {
106 if (IS_HIDDPARALLELUNIT_ATTR(tag
->ti_Tag
, idx
)) {
108 case aoHidd_ParallelUnit_Unit
:
109 unitnum
= (ULONG
)tag
->ti_Data
;
114 } /* while (tags to process) */
116 D(bug("!!!!Request for unit number %d\n",unitnum
));
118 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
121 data
= OOP_INST_DATA(cl
, obj
);
123 data
->baseaddr
= bases
[unitnum
];
124 data
->unitnum
= unitnum
;
128 * Enable the interrupt
130 parallel_outp(data
, UART_PCP
, UART_PCP_IRQ_EN
);
135 parallel_out(data
, PAR_PCP
, PAR_PCP_SLCT_IN
);
137 parallel_out(data
, PAR_PCP
, PAR_PCP_SLCT_IN
| PAR_PCP_INIT
);
143 D(bug("%s - an error occurred!\n",__FUNCTION__
));
145 ReturnPtr("ParallelUnit::New()", OOP_Object
*, obj
);
148 /******* ParallelUnit::Dispose() ***********************************/
149 OOP_Object
*PCParUnit__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
152 struct HIDDParallelUnitData
* data
;
154 EnterFunc(bug("ParallelUnit::Dispose()\n"));
157 data
= OOP_INST_DATA(cl
, obj
);
159 /* stop all interrupts */
160 serial_outp(data
, UART_PCP
, 0);
163 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
164 ReturnPtr("ParallelUnit::Dispose()", OOP_Object
*, obj
);
169 /******* ParallelUnit::Init() **********************************/
170 BOOL
PCParUnit__Hidd_ParallelUnit__Init(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Init
*msg
)
172 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
174 EnterFunc(bug("ParallelUnit::Init()\n"));
175 data
->DataReceivedCallBack
= msg
->DataReceived
;
176 data
->DataReceivedUserData
= msg
->DataReceivedUserData
;
177 data
->DataWriteCallBack
= msg
->WriteData
;
178 data
->DataWriteUserData
= msg
->WriteDataUserData
;
180 ReturnBool("ParallelUnit::Init()", TRUE
);
183 /******* ParallelUnit::Write() **********************************/
184 ULONG
PCParUnit__Hidd_ParallelUnit__Write(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Write
*msg
)
186 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
187 ULONG len
= msg
->Length
, count
;
189 // unsigned char status;
191 EnterFunc(bug("ParallelUnit::Write()\n"));
193 * If the output is currently stopped just don't do anything here.
195 if (TRUE
== data
->stopped
)
200 for(count
= 0; count
< len
; count
++)
202 parallel_out(data
, PAR_DATA
, msg
->Outbuffer
[count
]);
204 while((parallel_in(data
, PAR_SP
) & (PAR_SP_BUSY
| PAR_SP_ERROR
)) !=
205 (PAR_SP_BUSY
| PAR_SP_ERROR
))
211 parallel_out(data
, PAR_PCP
, PAR_PCP_SLCT_IN
| PAR_PCP_INIT
| PAR_PCP_STROBE
);
213 parallel_out(data
, PAR_PCP
, PAR_PCP_SLCT_IN
| PAR_PCP_INIT
);
217 ReturnInt("ParallelUnit::Write()",ULONG
, count
);
220 /******* ParallelUnit::Start() **********************************/
221 VOID
PCParUnit__Hidd_ParallelUnit__Start(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Start
*msg
)
223 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
226 * Allow or start feeding the UART with data. Get the data
229 if (TRUE
== data
->stopped
) {
230 if (NULL
!= data
->DataWriteCallBack
)
231 data
->DataWriteCallBack(data
->unitnum
, data
->DataWriteUserData
);
233 * Also mark the stopped flag as FALSE.
235 data
->stopped
= FALSE
;
239 /******* ParallelUnit::Stop() **********************************/
240 VOID
PCParUnit__Hidd_ParallelUnit__Stop(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Stop
*msg
)
242 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
245 * The next time the interrupt comes along and asks for
246 * more data we just don't do anything...
248 data
->stopped
= TRUE
;
251 /****** ParallelUnit::GetStatus ********************************/
252 UWORD
PCParUnit__Hidd_ParallelUnit__GetStatus(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_GetStatus
*msg
)
254 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
259 status
= parallel_in(data
, PAR_SP
);
261 if (status
& PAR_SP_BUSY
)
263 if (status
& PAR_SP_PE
)
265 if (status
& PAR_SP_SLCT
)
272 #if 0 /* !! STUFF BELOW DESABLED !! */
274 /************* The software interrupt handler that gets data from PORT *****/
277 #define READBUFFER_SIZE 513
279 AROS_UFH3(void, parallelunit_receive_data
,
280 AROS_UFHA(APTR
, iD
, A1
),
281 AROS_UFHA(APTR
, iC
, A5
),
282 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
286 struct HIDDSerialUnitData
* data
= iD
;
288 UBYTE buffer
[READBUFFER_SIZE
];
290 buffer
[len
++] = parallel_inp(data
, PAR_DATA
);
292 ** ... and deliver them to whoever is interested.
295 if (NULL
!= data
->DataReceivedCallBack
)
296 data
->DataReceivedCallBack(buffer
, len
, data
->unitnum
, data
->DataReceivedUserData
);
301 AROS_UFH3(void, parallelunit_write_more_data
,
302 AROS_UFHA(APTR
, iD
, A1
),
303 AROS_UFHA(APTR
, iC
, A5
),
304 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
308 struct HIDDParallelUnitData
* data
= iD
;
309 struct Message
* msg
;
312 ** Get the unixio message from my port and free it
314 msg
= GetMsg(data
->replyport_read
);
315 FreeMem(msg
, sizeof(struct uioMessage
));
318 ** Ask for more data be written to the unit
320 D(bug("Asking for more data to be written to unit %d\n",data
->unitnum
));
322 if (NULL
!= data
->DataWriteCallBack
)
323 data
->DataWriteCallBack(data
->unitnum
, data
->DataWriteUserData
);
328 #endif /* !! END DISABLED STUFF !! */
330 /******* init_parallelunitclass ********************************/
332 static int PCParUnit_Init(LIBBASETYPEPTR LIBBASE
)
334 ReturnInt("PCParUnit_Init", ULONG
, OOP_ObtainAttrBases(attrbases
));
338 static int PCParUnit_Expunge(LIBBASETYPEPTR LIBBASE
)
340 OOP_ReleaseAttrBases(attrbases
);
341 ReturnInt("PCParUnit_Expunge", int, TRUE
);
344 ADD2INITLIB(PCParUnit_Init
, 0)
345 ADD2EXPUNGELIB(PCParUnit_Expunge
, 0)