Siro
10.02.2014, 16:20
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 */
#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
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 */
#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