ругаться тут можно на
а) FIOxSET, FIOxCLR перед записью читать не нужно!!
б) нестандартные имена
в) некрасивый, на мой взгляд, вызов макроса
предпочёл бы P0.0_IN(); вместо P0.0_IN;
г) супер-мега-монстр типа дефайн-внутри-дефайна у меня не удался

но такой объем copy-paste... некрасиво...
я делал вот такую штуку
Код
// регистры Fast GPIO для LPC23xx
#define PORT0 0x3FFFC000
#define PORT1 0x3FFFC020
#define PORT2 0x3FFFC040
#define PORT3 0x3FFFC060
#define PORT4 0x3FFFC080
#define FIODIR(port) (*(volatile unsigned long *)(port + 0x00))
#define FIOMASK(port) (*(volatile unsigned long *)(port + 0x10))
#define FIOPIN(port) (*(volatile unsigned long *)(port + 0x14))
#define FIOSET(port) (*(volatile unsigned long *)(port + 0x18))
#define FIOCLR(port) (*(volatile unsigned long *)(port + 0x1C))
а потом определял кучу однотипных функций (надо было обращаться "поштучно" к 40 пинам, хаотично разбросанным по всем портам)
Код
#define DefPin(PinName,Port,BitNo) \
void Set##PinName (int val) \
{ \
FIODIR(Port) |= BIT(BitNo); \
if (val) FIOSET(Port) = BIT(BitNo); \
else FIOCLR(Port) = BIT(BitNo); \
} \
int Get##PinName (void) \
{ \
FIODIR(Port) &= ~BIT(BitNo); \
return (FIOPIN(Port) & BIT(BitNo)); \
}
DefPin (RST2, PORT1, 29);
можно расширить, скажем, так:
Код
#define PORT_IN(port,pin) FIODIR(port) &= ~(1UL<<(pin))
#define PORT_SET(port,pin) FIOSET(port) = (1UL<<(pin))
впрочем, эти макросы тоже заслуживают эпитетов "нестандартно" и "некрасиво"