Pointergefrickel als Makro
-
Ich arbeite momentan mit Mikrocontrollern und benutze defines um die Adressen von Registern zu kodieren.
z.B.
#define REGISTER_STATUS 0x04
Ich würde aber gerne, dass ich das Register in meinem Code dann auf diese Art und Weise die Werte in den Registern verändern kann:
REGISTER_STATUS |= 0x10
Das geht so natürlich nicht, ich benötige einen Pointer der auf die Adresse von REGISTER_STATUS zeigt, diesen muss ich dann dereferenzieren und z.B. die oben gezeigte Operation darauf ausführen.
Wie muss ich mein #define schreiben, dass das so intuitiv möglich ist wie gewünscht?
-
?
unsigned char *p = 0x04; *p = *p | 0x10;
-
#define REGISTER_STATUS (*(uint8_t*)0x04)
So vielleicht? Wie werden Register in deiner Umgebung angesprochen?
-
@Wutz Ja, genau das war mir zu umständlich.
@Singender Holzkübel Danke, genau das war es was ich gesucht habe!
-
ich mach sowas:
#define __REG(x) (*((volatile uint32_t *) x)) ... /* energy & clock managment */ #define CKEN __REG(0x41300004) /* Clock enable register */ ... #define CKEN_I2C (1 << 14) /* I2C unit clock */ ... /* I2C bus registers */ #define IBMR __REG(0x40301680) /* I2C Bus Monitor Register */ #define IDBR __REG(0x40301688) /* I2C Data Buffer Register */ #define ICR __REG(0x40301690) /* I2C Control Register */ #define ISR __REG(0x40301698) /* I2C Status register */ #define ISAR __REG(0x403016a0) /* I2C Slave Address Register */ ... #define IDBR_IDB (0xff) /* I2C Data Buffer (7 bit buffer for send/rec) */ #define ICR_FM (1 << 15) /* ICR:15 Fast Mode */ #define ICR_UR (1 << 14) /* ICR:14 Unit Reset */ #define ICR_SADIE (1 << 13) /* ICR:13 Slave Address Detected Interrupt Enable */ #define ICR_ALDIE (1 << 12) /* ICR:12 Arbitration Loss Detected Interrupt Enable */ #define ICR_SSDIE (1 << 11) /* ICR:11 Slave STOP Detected Interrupt Enable */ #define ICR_BEIE (1 << 10) /* ICR:10 Bus Error Interrupt Enable */ #define ICR_IRFIE (1 << 9) /* ICR:9 IDBR Receive Full Interrupt Enable */ #define ICR_ITEIE (1 << 8) /* ICR:8 IDBR Transmit Empty Interrupt Enable */ #define ICR_GCD (1 << 7) /* ICR:7 General Call Disable */ #define ICR_IUE (1 << 6) /* ICR:6 I2C Unit Enable */ #define ICR_SCLE (1 << 5) /* ICR:5 SCL Enable */ #define ICR_MA (1 << 4) /* ICR:4 Master Abort */ #define ICR_TB (1 << 3) /* ICR:3 Transfer Byte */ #define ICR_ACKNAK (1 << 2) /* ICR:2 ACK/Nak Control */ #define ICR_STOP (1 << 1) /* ICR:1 STOP */ #define ICR_START (1 << 0) /* ICR:0 START */ #define ISR_BED (1 << 10) /* ISR:10 Bus Error Detected */ #define ISR_SAD (1 << 9) /* ISR:9 Slave Adress Detected */ #define ISR_GCAD (1 << 8) /* ISR:8 General Call Address Detected */ #define ISR_IRF (1 << 7) /* ISR:7 IDBR Receive Full */ #define ISR_ITE (1 << 6) /* ISR:6 IDBR Transfer Empty */ #define ISR_ALD (1 << 5) /* ISR:5 Arbitration Loss Detected */ #define ISR_SSD (1 << 4) /* ISR:4 Slave STOP Detected */ #define ISR_IBB (1 << 3) /* ISR:3 I2C Bus Busy */ #define ISR_UB (1 << 2) /* ISR:2 Unit Busy */ #define ISR_ACKNAK (1 << 1) /* ISR:1 ACK/NAK Status */ #define ISR_RWM (1 << 0) /* ISR:0 Read/Write Mode */ #define ISAR_ISA (0x7f) /* ISAR:6:0 I2C Slave Address */
und dann im Code
int core_i2c_reset(uint8_t addr, int baudrate) { int baudrate_mask; /* baudrate_mask == 0 ==> ICR &= ~ICR_FM * else ICR |= ICR_FM */ CKEN &= ~CKEN_I2C; /* bringing down I2C clock */ CKEN |= CKEN_I2C; /* bringing up I2C clock */ if(baudrate == 100) baudrate_mask = 0; else if(baudrate == 400) baudrate_mask = 1; else return PANIC_CONF; /* resetting core, see pages 9-21, 9-22 from * Intel PXA255 developer's manual */ /* setting reset bit */ ICR |= ICR_UR; /* clear the ISR register */ ISR = 0; /* setting the address */ ISAR = ISAR_ISA & addr; /* enabling the i2c controller */ ICR |= ICR_IUE; /* enablind the SCL line */ ICR |= ICR_SCLE; /* setting the baudrate */ if(baudrate_mask) ICR |= ICR_FM; else ICR &= ~ICR_FM; /* clear reset in he ICR */ ICR &= ~ICR_UR; ICR |= ICR_BEIE | ICR_IRFIE | ICR_ITEIE; return 0; }