help me.
I am using KM34.
If you perform BME operation on port F as shown below, you will jump to a hard fault. Why?
Please let us know if you have a solution.
// #include "BME.h"
// #define BME_OPCODE_AND 1 / *! <AND opcode * /
// #define BME_OPCODE_OR 2 / *! <OR opcode * /
// # define BME_AND (ADDR) (* (volatile uint32_t *) (((uint32_t) ADDR) | (BME_OPCODE_AND << 26)))
// #define BME_OR (ADDR) (* (volatile uint32_t *) (((uint32_t) ADDR) | (BME_OPCODE_OR << 26)))
.
// # define GPIOE_BASE (0x400FF040u)
// #define GPIOE ((GPIO_Type *) GPIOE_BASE)
.
// # define GPIOF_BASE (0x400FF041u)
// #define GPIOF ((GPIO_Type *) GPIOF_BASE)
(BME_OR (& GPIOE-> PDOR) = (1u << 3)); <-OK
(BME_AND (& GPIOE-> PDOR) = ~ (1u << 3)); <-OK
(BME_AND (& GPIOF-> PDOR) = ~ (1u << 5)); <-goto HardFault_Handler
thank you.
Solved! Go to Solution.
I do not have the header here to look at.
The datasheet says "400F_F041 Port Data Output Register (GPIOF_PDOR)", which is different than GPIO base. So:
#define GPIOF_BASE (0x400FF041u)
& GPIOF-> PDOR
is going to point to F041 + the offset of PDOR which is likely to be an invalid address.
Hard to say here as GPIOF may be different or same as GPIOF_BASE, not having the header at hand.
PORTE probably works because it points to an address that is not invalid.
However it is not pointing to where you want to be.
Try using &GPIOE_PDOR and &GPIOF_PDOR which would correspond to the PDOR addresses in the datasheet.
I did not see that the base addresses where given in the data sheet.
Someone from NXP needs to clear up the discrepancy between the header and the datasheet.
There is also this note in the Reverence Manual:
4.8.1 GPIO accessibility in the memory map
The GPIO is multi-ported and can be accessed directly by the core with zero wait states at
base address 0xF800_0000. It can also be accessed by the core and DMA masters
through the cross bar/AIPS interface at 0x400F_F000 and at an aliased slot (15) at
address 0x4000_F000. All BME operations to the GPIO space can be accomplished
referencing the aliased slot (15) at address 0x4000_F000. Only some of the BME
operations can be accomplished referencing GPIO at address 0x400F_F000.
I really hate datasheets like this. What does 'some' mean here? We are left to guess...
"// # define GPIOF_BASE (0x400FF041u)"
It is unlikely that PORTF has a odd (vs even) address.
Not sure if this is only an example or that the supplied headers are not being used.
Always best to use the supplied headers. Alas they have been known to be wrong at times.
I assume the clock to PORTF was enabled as well.
Also better to use UL as s suffix for portability, than just u.
Thank you for your teaching.
I would be grateful if you could teach me three more points.
(1)
For GPIOF, I am using the attached MKM34Z7.h, which is on line 5446. Is this header wrong?
The CPU uses MKM34Z256VLL7.
/ ** Peripheral GPIOF base address * /
#define GPIOF_BASE (0x400FF041u)
/ ** Peripheral GPIOF base pointer * /
(2)
In the reference manual, there is the following table and the following sentences, but is it okay to use the address in (1)?
---
Kinetis KM34 Sub-Family Reference Manual, Rev. 3, 09/2017 - 20.3.3 Additional details on decorated addresses and GPIO accesses
・・・
As a result, undecorated GPIO references and decorated AND, OR, XOR, LAC1 and
LAS1 operations can use the standard 0x400F_F000 base address, while decorated BFI
and UBFX operations must use the alternate 0x4000_F000 base address. Another
implementation can simply use 0x400F_F000 as the base address for all undecorated
GPIO accesses and 0x4000_F000 as the base address for all decorated accesses. Both
implementations are supported by the hardware.
---
(3)
The address for MBE is in the table, but the value corresponding to GPIO is unknown.
Please tell us some actual addresses of GPIOA to GPIOF.
Peripheral address space : 0x4400_0000–0x4FFF_FFFF
Decorated AND, OR, XOR, LAC1, LAS1 references to peripherals and GPIO based at either 0x4000_F000 or 0x400F_F000
I do not have the header here to look at.
The datasheet says "400F_F041 Port Data Output Register (GPIOF_PDOR)", which is different than GPIO base. So:
#define GPIOF_BASE (0x400FF041u)
& GPIOF-> PDOR
is going to point to F041 + the offset of PDOR which is likely to be an invalid address.
Hard to say here as GPIOF may be different or same as GPIOF_BASE, not having the header at hand.
PORTE probably works because it points to an address that is not invalid.
However it is not pointing to where you want to be.
Try using &GPIOE_PDOR and &GPIOF_PDOR which would correspond to the PDOR addresses in the datasheet.
I did not see that the base addresses where given in the data sheet.
Someone from NXP needs to clear up the discrepancy between the header and the datasheet.
There is also this note in the Reverence Manual:
4.8.1 GPIO accessibility in the memory map
The GPIO is multi-ported and can be accessed directly by the core with zero wait states at
base address 0xF800_0000. It can also be accessed by the core and DMA masters
through the cross bar/AIPS interface at 0x400F_F000 and at an aliased slot (15) at
address 0x4000_F000. All BME operations to the GPIO space can be accomplished
referencing the aliased slot (15) at address 0x4000_F000. Only some of the BME
operations can be accomplished referencing GPIO at address 0x400F_F000.
I really hate datasheets like this. What does 'some' mean here? We are left to guess...