-
        

Ergebnis 1 bis 3 von 3

Thema: BIT BANDING auf GPIO's beim LPC17xx

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    521

    BIT BANDING auf GPIO's beim LPC17xx

    Anzeige

    Hallo zusammen. Ich beschäftige mich grade mit dem Bit-Banding beim LPC1768
    Sinn und Zweck ist die Ausführung von "atomaren" code für Bitmanipulationen auf den GPIO's

    Alle Versuche auf die GPIO's mittels Bit-Banding zuzugreifen landen aber bei mir im HardFault_Handler
    zumindest mit den überall veröffentlichen Macros bzw. include Files.
    Auf andere Register funktioniert es, die haben aber auch einen völlig anderen Adressbereich.

    Die GPIO's haben die physikalischen Adressen 0x2009 C0xx
    Dazu zählen die Register FIO SET CLR PIN MASK DIR

    Laut Datenblatt befinden sich die "peripheral bit band alias adressen" ab 0x4200 0000
    die sind aber NICHT für die GPIO's gedacht.

    Das Register WDT phsikalisch 0x4000.0000 liegt Bittechnisch an den Adressen 0x4200.0000 bis 0x420.001F
    Ich habe es auch ausprobiert und dort Bits gesetzt. Funktioniert einwandfrei.

    Welche Bit-Banding Adresse hat aber z.B. das FIO0SET Register ?
    geht das Bitbanding überhaupt auf den GPIO's

    Laut Datenblatt ja:
    UM10360 Page 6 of 841
    All GPIOs are located on an AHB bus for fast access, and support Cortex-M3 bit-banding.

    auf Seite 13 ist der AHB Bus in einem anderem Bereich als die GPIO's
    UM10360 page 13 of 841
    GPIO 0x2009 C000 - 0x2009 FFFF
    APB 0x4000 0000 - 0x4007 FFFF
    AHB 0x5000 0000 - 0x501 FFFF

    Ich bin jetzt der Meinung es geht nicht aber ich HOFFE Ihr könnt mich eines Besseren belehren

    Erwartungsvoll
    Siro


    perSetBit(LPC_FIO0PIN,0); /* setzte Bit 0 am Port 0 , führt zum HardFault_Handler */



    Code:
    #ifndef BitBanding_Included    
      #define Bitbanding_Included
    
    #define RAM_BASE    0x20000000UL  /* normal RAM Base address */
    #define RAM_BB_BASE 0x22000000UL  /* Bit Banding Base address for RAM */
    
    #define PER_BASE    0x40000000UL  /* normal periperal Base address */
    #define PER_BB_BASE 0x42000000UL  /* Bit Banding peripheral Base address for RAM */
    
    /* macros for bit manipulation in RAM */
    #define _varClrBit(VarAddr, BitNumber) \
    (*(U32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 0)
    
    #define _varSetBit(VarAddr, BitNumber) \
    (*(U32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 1)
    
    #define _varGetBit(VarAddr, BitNumber) \
    (*(U32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)))
    
    
    /* macros for bit manipulation in peripheral registers  */
    #define _perClrBit(PerAddr, BitNumber) \
    (*(U32 *) (PER_BB_BASE | ((PerAddr - PER_BASE) << 5) | ((BitNumber) << 2)) = 0)
    
    #define _perSetBit(PerAddr, BitNumber) \
    (*(U32 *) (PER_BB_BASE | ((PerAddr - PER_BASE) << 5) | ((BitNumber) << 2)) = 1)
    
    #define _perGetBit(PerAddr, BitNumber) \
    (*(U32 *) (PER_BB_BASE | ((PerAddr - PER_BASE) << 5) | ((BitNumber) << 2)))
    
    
    /* with these macros we can easily work with bits in atomic code */
    #define varClrBit(var,bit) (_varClrBit((U32)&var,bit))
    #define varSetBit(var,bit) (_varSetBit((U32)&var,bit))
    #define varGetBit(var,bit) (_varGetBit((U32)&var,bit))
    
    #define perClrBit(var,bit) (_perClrBit((U32)&var,bit))
    #define perSetBit(var,bit) (_perSetBit((U32)&var,bit))
    #define perGetBit(var,bit) (_perGetBit((U32)&var,bit))
    
    #endif
    Geändert von Siro (10.02.2014 um 16:26 Uhr)

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    521
    Das Problem ist gelöst:

    Die GPIO's befinden sich NICHT im Peripherie Bereich, sondern im SRAM Bereich
    und so muss ich die anderen Macros benutzen.

    also NICHT perSetBit(LPC_FIO0PIN,0); sondern varSetBit(LPC_FIO0PIN,0);

    Die Firma NXP hat mir auch zurück geschrieben mit einem zusätzlichen Hinweis:
    Code:
    Bit-banding is possible, since the GPIO's are in the Cortex-M3 "SRAM" area.
    
    Example for GPIO1.28:
    #define BITBAND_SRAM(a,b) ((volatile uint32_t *)((0x22000000 + ((uint32_t)(a)-0x20000000)*32)))[b]
    #define LED    BITBAND_SRAM(&GPIO1->FIOPIN, 28)
    
    This only makes sense for the FIOPIN or FIODIR registers, not for FIOSET  and FIOCLR. Note that bit-banding performs a read-modify-write  operation on the peripheral register when writing by bit-banding!
    
    Also note that writing to FIOPIN by bit-banding requires a __DSB()  instruction afterwards. This is due to the structure of the GPIO block.
    
    Example:
    LED = 1;
    __DSB();

    Im IAR-COMPILER kann das __DSB(); wie folgt geschrieben werden:

    __asm("DSB");
    /* ein doppelter Unterstrich */

    Die Funktion ansich ist auch ohne das DSB (Data Synchronisation Barrier) gegeben. Aber das DSB stellt sicher, daß die intgerne Verarbeitung auch fertig geworden ist.
    "The DSB instruction completes when all explicit memory accesses before it complete."
    Geändert von Siro (11.02.2014 um 11:28 Uhr)

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    521
    Thread Sicheres Bit Setzen und Löschen auf den GPIO's (der Vollständigkeit halber)

    Nun funktioniert es endlich

    Code:
    #define BITBAND_SRAM(a,b) ((volatile U32 *)((0x22000000 + ((U32)(a)-0x20000000)*32)))[b]
    #define BIT_SET_GPIO(port,bit) BITBAND_SRAM(&port,bit) = 1;  __asm("DSB") 
    #define BIT_CLR_GPIO(port,bit) BITBAND_SRAM(&port,bit) = 0;  __asm("DSB")

    Nun kann mit folgendem Code ein einzelnes Bit verändert werden OHNE dass ein Interrupt
    oder anderer Task während der Sequenz auch das Bit verändert. Wir haben einen atomaren Code, der auch einigermaßen übersichtlich ist.

    Beispiele:

    BIT_SET_GPIO(LPC_FIO1PIN,31); /* setze Bit 31 vom Port P1 */
    BIT_CLR_GPIO(LPC_FIO1PIN,31); /* lösche Bit 31 vom Port P1 */

    BIT_SET_GPIO(LPC_FIO0PIN,12); /* setze Bit 12 vom Port P0 */
    BIT_CLR_GPIO(LPC_FIO0PIN,12); /* lösche Bit 12 vom Port P0 */

Ähnliche Themen

  1. [ERLEDIGT] Problem mit GPIO beim Raspberry Pi
    Von Kampi im Forum Raspberry Pi
    Antworten: 19
    Letzter Beitrag: 25.08.2012, 18:49
  2. 8 Bit stand alone PWM auf 16 Bit aufgebohrt
    Von The Man im Forum Assembler-Programmierung
    Antworten: 4
    Letzter Beitrag: 28.11.2008, 13:26
  3. Antworten: 11
    Letzter Beitrag: 28.08.2006, 17:23
  4. 10 bit auf einmal vergleichen ?
    Von Bunch im Forum AVR Hardwarethemen
    Antworten: 7
    Letzter Beitrag: 27.10.2005, 11:02
  5. 16 Bit auf 2x 8Bit aufteilen....
    Von Magge2k im Forum Software, Algorithmen und KI
    Antworten: 3
    Letzter Beitrag: 06.07.2005, 19:02

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •