Skip to content
Advertisement

How to write to data register in C, without touching previous writes?

Iam a beginner in C and have this scenario:

I can successfully write to a gpio port with data register 0x103 and direction register 0x95. If I want to write to another pin I have to “overwrite” the previously pin.

As if I first write 00010000 and then want to make another pin high I need to write 00010001 to not make the first “1” low.

Suggestions?

Here is my code:

#include <stdio.h>
#include <stdio.h>
#include <sys/io.h>
#define outportb(a,b) outb(b,a)
#define inportb(a) inb(a)

void main(void)
{
    iopl(3); 
    /* set GPIO port1[7-0] as output mode */
    outportb(0x95, 0xff);

    /* write data to GPIO port1 */
    outportb(0x103, 0x11); 
} 

Advertisement

Answer

Output ports are often readable, so where you have

outportb(0x103, 0x10);                      // set b4
...
outportb(0x103, 0x11);                      // set b1 and b4

You can do, say

outportb(0x103, 0x10);                      // set b4
...
outportb(0x103, inportb(0x103) | 0x01);     // set b0 too

But sometimes it is not recommended to read / modify / write an output port. Anyway it is cleaner to keep a copy of the output state, modify that, and write it to the port

unsigned char bcopy = 0;                    // init port output
outportb(0x103, bcopy);
...
bcopy |= 0x10;                              // set b4
outportb(0x103, bcopy);
...
bcopy |= 0x01;                              // set b0
outportb(0x103, bcopy);
...
bcopy &= 0xEF;                              // now clear b4
outportb(0x103, bcopy);

Or as one-liners:

outportb(0x103, bcopy = 0);                 // init port
...
outportb(0x103, bcopy |= 0x10);             // set b4
...
outportb(0x103, bcopy |= 0x01);             // set b0
...
outportb(0x103, bcopy &= 0xEF);             // now clear b4
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement