Port C documentation Errors

Hi,I had some trouble Programming the Port C because I unfortunately read the wrong lines in the net+50 manual on Page 93 (Port C) “Reading DATA field provides the current state of the signal regardless of its configuration mode.” This is wrong, 10 lines lower you read that this is the interrupt pending bit for ports C0-C3 when in interrupt mode. “Writing a DATA bit when configured in GPIO input mode or in special function mode has no effect” This seems to be also wrong because the next sentence says that this is the interrupt clear register in special function mode for C0-C3. When you want to modify a single bit in the port C-Register you have to clear the lower 4 Bits if they are in special function mode and you don’t want to clear an interrupt by accident. A Bit which is not in special function mode has to be written back unmodified. But I’m not sure because my interrupthandler works even when I do not clear the interrupts in the Port C register (In a device driver using uCLinux-2.4.20) ??? Does anybody know why ? Can I simplify my atomic read-modify-write to Port C because writing 1 does’nt clear interrupts ? Jochen

What you write is true. I had this problem a while ago when I accidentally acknowledged an interrupt which occured just in the moment I tried to modify another bit of PORTC. The following code is my result. Generally you have to disable interrupts because changing one bit is a read-modify-writy cycle and another thread or ISR could also access the PORTC modifying another bit between your read and write cycles. Since I wanted my code not to need to know which port-bits are configured as interrupt, I have it read the ‘mode’ field of PORTC and clear those bits before I write data back. This code compiles to about 30 instructions and runs in about 6

Here is the code: #define PORTC_ADDR 0xffb00028 void Set_PORTC4_level(char new_level) { unsigned long post, reg, mode; post = tx_interrupt_control(TX_INT_DISABLE); reg = ((unsigned long)PORTC_ADDR); mode = (0xff000000 & reg) >> 24; // get MODE field reg &= ~mode; // clear all SF bits to prevent acknowledging interrupts reg &= ~(1<<4); // clear bit 4 reg |= (1&new_level) << 4; // set bit 4 to requested value ((unsigned long)PORTC_ADDR) = reg; tx_interrupt_control(post); }