After hacking the doorbell I did some code to make it ring and flash.
I’m new to software development on Linux. Doing my work in Eclipse with CDT has been fun so far.
Probably the hardest thing for me was figuring out that my printer port card not on a standard I/O address.
Parallel ports are going away on modern PCs but they are still easy to find in PCI interface cards.
I purchased mine from Wright Hobbies a good while ago.
I did a quick look and found a lot for $10, some including 2 serial ports.
Here is my code, with comments that should explain what’s going on. The source file is available below. Let me know of any suggested improvements.
IOPortTest.c Source
. You should be able to compile this straight from the Linux shell with “gcc IOPortTest.h –o IOPortTest”
This is just test code. I plan on restructuring it into a reusable module for use in future projects. I like the idea of using a full PC for interfacing projects. Its a great development environment.
1: /*
2: * IOPortTest uCHobby 8.20.2010
3: * sets bit 0 and 1 of the Parallel port Data pins high for 10mS.
4: * These two bits are pins 2 and 3 on the standard DB25 connector.
5: *
6: * Two methods are shown, the first using IOCTL calls,the second
7: * uses direct I/O writes. To use direct writes we need to know
8: * the IO port addresses, I found mine by hunting through boot
9: * up messages.
10: */
11:
12: #include <stdlib.h>
13: #include <stdio.h>
14: #include <unistd.h>
15:
16: #include <fcntl.h>
17: #include <sys/ioctl.h>
18: #include <sys/io.h>
19: #include <linux/ppdev.h>
20: #include <linux/parport.h>
21:
22: void ToggleWithIOCTL(void);
23: void ToggleWithIORaw(void);
24:
25: int main() {
26: ToggleWithIOCTL(); //Use the IOCTL driver method to toggle the pins
27: sleep(1); //Sleep for one second
28: ToggleWithIORaw(); //This time use the raw IO methods to toggle the pins
29: exit(EXIT_SUCCESS);
30: }
31:
32: //Use IOCTL calls to control printer port IO - Works well.
33: void ToggleWithIOCTL (void){
34: int portHandle; //Handle to reference the parallel port as a file
35:
36: portHandle=open("/dev/parport0", O_RDWR); //Open the port.
37: if (portHandle == -1) { //Did the port fail to open?
38: perror ("open"); //Could not open, output error with an explanation
39: }
40:
41: if (portHandle != -1) { //if the port opened OK, claim it for our purposes
42: if (ioctl (portHandle, PPCLAIM)) { //Were we able to claim it?
43: perror ("PPCLAIM"); //Cannot claim port, output an explanation
44: close (portHandle); //Close the file we had
45: portHandle=-1; //set the handle to show not-valid
46: }
47: }
48:
49: if(portHandle != -1){ //Do we have a valid file handle?
50: int iTemp=0x03; //Just need to turn on the lower two bits, D0 and D1,
51: //leave D2-D7 low. Use a temp because we have to pass
52: //by reference.
53: if(ioctl(portHandle, PPWDATA,&iTemp)) { //Set the port value
54: printf("PPWDATA"); //Write failed, output error with an explanation
55: }
56:
57: usleep(10000); //Sleep for 10 milliseconds, value is in microseconds.
58:
59: iTemp=0x00; //turn off all the bits D0-D7
60: if(ioctl(portHandle, PPWDATA,&iTemp)) { //Set the port value
61: printf("PPWDATA"); //Write failed, output error with an explanation
62: }
63: }
64:
65: if(ioctl(portHandle, PPRELEASE)) { //Try and release the ppdev file handle
66: printf("PPRELEASE"); //Did not release, output an explanation
67: }
68: close(portHandle);
69: }
70:
71: #define PPDEV_BASEPORT 0xC400 //Found by hunting in boot messages near ppdev
72: #define PPDEV_DATA (PPDEV_BASEPORT+0) //Define constant for the DATA port
73: #define PPDEV_STATUS (PPDEV_BASEPORT+1) //Define constant for the STATUS port
74: #define PPDEV_CONTROL (PPDEV_BASEPORT+2) //Define constant for the CONTROL port
75:
76: #define TRUE 1 //These should be defined somewhere in a generic module,
77: #define FALSE 0 //for now I'm defining them here.
78:
79: //Use raw I/O method to control printer port IO
80: void ToggleWithIORaw (void) {
81: int portOK=FALSE;
82:
83: if(iopl(3)){ //Request permission to access IO ports using raw
84: //functions. This may not be necessary
85: perror("iopl"); //No permission, output error with an explanation
86: }
87: else { //We got permission
88: /* Get access to the ports */
89: if (ioperm(PPDEV_BASEPORT, 3, 1)) { //Get permission to access the
90: //specific ports we need.
91: perror("ioperm"); //No permission, output error with an explanation
92: exit(EXIT_FAILURE); //We are done, bad code should not exit here
93: }
94: else {
95: portOK=TRUE; //We have permission and have claimed the ports we need
96: }
97: }
98:
99: if (portOK) {
100: outb(0x03, PPDEV_DATA); //Set the lower two bits of DATA register.
101: usleep(10000); //Sleep for 10 milliseconds, in microseconds.
102: outb(0x00, PPDEV_DATA); //turn off all the bits D0-D7
103: }
104:
105: if (ioperm(PPDEV_BASEPORT, 3, 0)) { //Release the IO ports
106: perror("ioperm"); //Could not release, output error with an explanation
107: portOK=FALSE; //We had some trouble ending port access.
108: }
109: // return(portOK); //not returning value right now.
110: }
One Response
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
Continuing the Discussion