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;
    }
    

Anmelden zum Antworten