e_holen%vax.runit.unit.uninett@TOR.NTA.NO (Endre Holen) (04/06/88)
I want to write a device driver to a graphics board that sits in the AT-compatible bus in a DN3000. The driver should only do the following : Read and write to the Status port Read and write to the data port These two ports are at base adress and base+2 . The documentation for using GPIO calls are rather poor, (or maybe I am stupid), but I have a bit problems with finding out how to get access to the CSR page. Has anybody done something similar ? Endre Holen Super Computing Centre University of Trondheim
trb@stag.UUCP ( Todd Burkey ) (04/11/88)
In article <66*e_holen@vax.runit.unit.uninett> e_holen%vax.runit.unit.uninett@TOR.NTA.NO (Endre Holen) writes: > >The documentation for using GPIO calls are rather poor, (or maybe I am stupid), but I have a bit problems with finding out how to get access to the CSR page. > I have had similar problems dealing with the Aegis GPIO docs. For the life of me, I can't figure out how to get the PBU Control call to work correctly (I want to swap words). All I can figure out is that it may be a NOP command when combined with the PBU map controller command (the 20 bit call option...I am writing this from home, so can't remeber the exact call syntax's). The docs reference manual made no mention of what sequencing was necessary for the calls and the example sets didn't include the swap words/bytes options. Guess I will have to break all my datastructures down to the a.xref_point.value.up:=b.point.value.up a.xref_point.value.lo:=b.point.value.lo level of coding...what a waste. -Todd Burkey trb@stag.UUCP
ced@apollo.uucp (Carl Davidson) (04/19/88)
From article <372@stag.UUCP>, by trb@stag.UUCP ( Todd Burkey ): > I have had similar problems dealing with the Aegis GPIO docs. For the > life of me, I can't figure out how to get the PBU Control call to work > correctly (I want to swap words). All I can figure out is that it may > be a NOP command when combined with the PBU map controller command > (the 20 bit call option...I am writing this from home, so can't > remeber the exact call syntax's). The docs reference manual made no > mention of what sequencing was necessary for the calls and the example > sets didn't include the swap words/bytes options. Guess I will have to > break all my datastructures down to the > > a.xref_point.value.up:=b.point.value.up > a.xref_point.value.lo:=b.point.value.lo > > level of coding...what a waste. > > -Todd Burkey > trb@stag.UUCP I ran into a similar problem about a year ago when coding a driver and have a solution for you. Assuming that you are running something other than SR9.7, and that you are coding your driver in C, you can do the following: In the source file in which you call pbu_$control make the following definitions: #define NULL_SET 0 #define MAP_R 1 #define MAP_RW 2 #define SWAP_OFF 4 #define SWAP_WORDS 8 #define SWAP_BYTES 16 You need to do this because until recently /sys/ins/pbu.ins.c had incorrect definitions for the Pascal set PBU_$OPTS_T (this has been fixed on SR 9.7, at least, maybe earlier) and this resulted in the call failing silently. Well, actually, it resulted in the call doing what you told it to do, but not what you wanted it to. You can then call pbu_$control as follows: pbu_$control(*unit, SWAP_WORDS + MAP_RW, old_opts, 0, status -> all); This will give you word swapping AND byte swapping (i.e. everything you write across the bus will be treated the same way). You need to read Chapter 1, section 1.4 of Rev 10 of the GPIO manual to understand why this is so. The explanation is too long to repeat here. If you are writing in Pascal, or are already on SR9.7, and you are still having trouble, it is *probably* because you are not driving a 20-bit Multibus (that doesn't appear to be the case here, but this call is a no-op for any other bus - AT, VME, or 16-bit Multibus). It is important for C programmers to remember that any parameter passed into the initialization routine (this is where you should be calling pbu_$control) is passed by *reference* and is therefore a pointer and needs to be de-referenced before being passed to any system calls because of the STD_$CALL convention. This is why both unit and status.all are de-referenced in the example above. You can test the results of your call to pbu_$control by making another call to pbu_$control with a null set (NULL_SET) as the second parameter and printing out the value returned in "old_opts". I do this with: pbu_$control(*unit, NULL_SET, old_opts, 0, status -> all); printf("\nPBU_$CONTROL is %d \n", old_opts); It ain't pretty, but it works. Also, if you would like to see your initialization routine run in the debugger, you can declare a do-nothing initialization routine in the DDF and call the real initialization routine from your test program. This is also the easiest way to debug interrupt service routines. In the ISR case, your test program needs to wait on the PBU event count and then call the ISR when it advances. Using this method I have successfully debugged ISRs installed in the call library and then moved them to the interrupt library when they are "bug-free". In one case, we located latent controller firmware bugs in a matter of minutes that would have taken hours or days the conventional way. If none of this helps, drop me some mail and I'll be glad to help further. This technique also works well for interrupt service routines. In -- --Carl Davidson "Science is what you do Apollo Computer Inc. after you guess well." Chelmsford, MA 01824 {decvax,mit-eddie,umix}!apollo!ced