Why does BME operation for GPIO causes the hard fault?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why does BME operation for GPIO causes the hard fault?

Jump to solution
1,115 Views
yasuhikokoumoto
Senior Contributor I

Hello experts,

I have a question regarding BME operation for GPIO.
I am using FRDM-KL25Z and KSDK 1.3.
The following code causes the hard fault when BME accessed GPIO areas.
I think some register setting would be lost, but I cannot find what it is.
The codes had worked with the previoys sample code of KL25_SC environment.
Can anyone help me?


Best regards,
Yasuhiko Koumoto.

#define BME_BFI_MASK(BIT,WIDTH)  (1<<28) | (BIT<<23) | ((WIDTH-1)<<19) #define BME_BFI_W(addr, bit, width)  \           (*(volatile uint32_t*)((uint32_t)addr | BME_BFI_MASK(bit,width)))

void my_wait(void) {   volatile int i;   for(i=0;i<0x50000;i++); }

int main(void) {     SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTD_MASK;     // RED LED Initialization     PORTB_PCR18 &= ~PORT_PCR_MUX_MASK;     PORTB_PCR18 |= PORT_PCR_MUX(1);     GPIOB_PDDR |= (1<<18);

    // Yellow LED Initialization     PORTB_PCR19 &= ~PORT_PCR_MUX_MASK;     PORTB_PCR19 |= PORT_PCR_MUX(1);     GPIOB_PDDR |= (1 << 19);

    // Blue LED Initialization     PORTD_PCR1 &= ~PORT_PCR_MUX_MASK;     PORTD_PCR1 |= PORT_PCR_MUX(1);     GPIOD_PDDR |= (1 << 1);      while(1) {         BME_BFI_W(&GPIOB_PCOR, 18, 1) = (1<<18);         BME_BFI_W(&GPIOB_PSOR, 19, 1) = (1<<19);         BME_BFI_W(&GPIOD_PSOR,  1, 1) = (1<<1);         my_wait();         BME_BFI_W(&GPIOB_PSOR, 18, 1) = (1<<19);         BME_BFI_W(&GPIOB_PCOR, 19, 1) = (1<<18);         BME_BFI_W(&GPIOD_PSOR,  1, 1) = (1<<1);         my_wait();         BME_BFI_W(&GPIOB_PSOR, 18, 1) = (1<<18);         BME_BFI_W(&GPIOB_PSOR, 19, 1) = (1<<19);         BME_BFI_W(&GPIOD_PCOR,  1, 1) = (1<<1);         my_wait();          BME_BFI_W(&GPIOB_PSOR, 18, 1) = (1<<18);         BME_BFI_W(&GPIOB_PSOR, 19, 1) = (1<<19);         BME_BFI_W(&GPIOD_PSOR,  1, 1) = (1<<1);         my_wait();     } }

0 Kudos
Reply
1 Solution
924 Views
yasuhikokoumoto
Senior Contributor I

Hello everyone,

the problem was solved.

I have forgotten that the GPIO address could not be used as itself in the case of BME BFI and BFX.

Therefore the GPIO address should be converted as the following.

Now, the code works successfully.

#define BME_BFI_MASK(BIT,WIDTH)  (1<<28) | (BIT<<23) | ((WIDTH-1)<<19)

#define BME_BFI_W(addr, bit, width)  \

          (*(volatile uint32_t*)((uint32_t)addr | BME_BFI_MASK(bit,width)))

#define GPIOB_PSOR_ALIAS 0x4000F044

#define GPIOB_PCOR_ALIAS 0x4000F048

#define GPIOD_PSOR_ALIAS 0x4000F0C4

#define GPIOD_PCOR_ALIAS 0x4000F0C8

void my_wait(void)

{

  volatile int i;

  for(i=0;i<0x500000;i++);

}

int main (void)

{

    SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK                 | SIM_SCGC5_PORTB_MASK                 | SIM_SCGC5_PORTC_MASK                 | SIM_SCGC5_PORTD_MASK                 | SIM_SCGC5_PORTE_MASK );     // 赤色LEDの初期設定     PORTB_PCR18 &= ~PORT_PCR_MUX_MASK;  // PORTB_PCRレジスタのMUXを000     PORTB_PCR18 |= PORT_PCR_MUX(1);    // PTB18のMUXを001にセット(GPIOを選択)     GPIOB_PDDR |= (1<<18);              // PTB18を出力に設定

    // 緑色LEDの初期設定     PORTB_PCR19 &= ~PORT_PCR_MUX_MASK;     PORTB_PCR19 |= PORT_PCR_MUX(1);    // PTB19のMUXを001にセット(GPIOを選択)     GPIOB_PDDR |= (1 << 19);            // PTB19出力に設定

    // 青色LEDの初期設定     PORTD_PCR1 &= ~PORT_PCR_MUX_MASK;     PORTD_PCR1 |= PORT_PCR_MUX(1);      // PTD1のMUXを001にセット(GPIOを選択)     GPIOD_PDDR |= (1 << 1);            // PTD1を出力に設定         while(1) {               BME_BFI_W(GPIOB_PCOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを赤色に)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をHighに設定(LEDを消灯)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを消灯)         my_wait();                      // 適当に待ち時間を入れる

        BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をHighに設定(LEDを消灯)         BME_BFI_W(GPIOB_PCOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを緑色に)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを消灯)         my_wait();                          // 適当に待ち時間を入れる

        BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを消灯)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを消灯)         BME_BFI_W(GPIOD_PCOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを青色に)         my_wait();                          // 適当に待ち時間を入れる                 BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを消灯)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを消灯)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をLowに設定(LEDを消灯)         my_wait();                          // 適当に待ち時間を入れる     }

Best regards,

Yasuhiko Koumoto.

View solution in original post

0 Kudos
Reply
2 Replies
924 Views
yasuhikokoumoto
Senior Contributor I

Hello,

additional information is that the hard fault occurs when CPU accesses to the address 0x5900xxxx.

Although I don't know well, is the address 0x5900xxxx out of the range of the default MPU settings?

Does the KSDK 1.3 use MPU?

Best regards,

Yasuhiko Koumoto.

0 Kudos
Reply
925 Views
yasuhikokoumoto
Senior Contributor I

Hello everyone,

the problem was solved.

I have forgotten that the GPIO address could not be used as itself in the case of BME BFI and BFX.

Therefore the GPIO address should be converted as the following.

Now, the code works successfully.

#define BME_BFI_MASK(BIT,WIDTH)  (1<<28) | (BIT<<23) | ((WIDTH-1)<<19)

#define BME_BFI_W(addr, bit, width)  \

          (*(volatile uint32_t*)((uint32_t)addr | BME_BFI_MASK(bit,width)))

#define GPIOB_PSOR_ALIAS 0x4000F044

#define GPIOB_PCOR_ALIAS 0x4000F048

#define GPIOD_PSOR_ALIAS 0x4000F0C4

#define GPIOD_PCOR_ALIAS 0x4000F0C8

void my_wait(void)

{

  volatile int i;

  for(i=0;i<0x500000;i++);

}

int main (void)

{

    SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK                 | SIM_SCGC5_PORTB_MASK                 | SIM_SCGC5_PORTC_MASK                 | SIM_SCGC5_PORTD_MASK                 | SIM_SCGC5_PORTE_MASK );     // 赤色LEDの初期設定     PORTB_PCR18 &= ~PORT_PCR_MUX_MASK;  // PORTB_PCRレジスタのMUXを000     PORTB_PCR18 |= PORT_PCR_MUX(1);    // PTB18のMUXを001にセット(GPIOを選択)     GPIOB_PDDR |= (1<<18);              // PTB18を出力に設定

    // 緑色LEDの初期設定     PORTB_PCR19 &= ~PORT_PCR_MUX_MASK;     PORTB_PCR19 |= PORT_PCR_MUX(1);    // PTB19のMUXを001にセット(GPIOを選択)     GPIOB_PDDR |= (1 << 19);            // PTB19出力に設定

    // 青色LEDの初期設定     PORTD_PCR1 &= ~PORT_PCR_MUX_MASK;     PORTD_PCR1 |= PORT_PCR_MUX(1);      // PTD1のMUXを001にセット(GPIOを選択)     GPIOD_PDDR |= (1 << 1);            // PTD1を出力に設定         while(1) {               BME_BFI_W(GPIOB_PCOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを赤色に)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をHighに設定(LEDを消灯)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを消灯)         my_wait();                      // 適当に待ち時間を入れる

        BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をHighに設定(LEDを消灯)         BME_BFI_W(GPIOB_PCOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを緑色に)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを消灯)         my_wait();                          // 適当に待ち時間を入れる

        BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを消灯)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを消灯)         BME_BFI_W(GPIOD_PCOR_ALIAS,  1, 1) = (1<<1); // PTD1をHighに設定(LEDを青色に)         my_wait();                          // 適当に待ち時間を入れる                 BME_BFI_W(GPIOB_PSOR_ALIAS, 18, 1) = (1<<18); // PTB18をLowに設定(LEDを消灯)         BME_BFI_W(GPIOB_PSOR_ALIAS, 19, 1) = (1<<19); // PTB19をLowに設定(LEDを消灯)         BME_BFI_W(GPIOD_PSOR_ALIAS,  1, 1) = (1<<1); // PTD1をLowに設定(LEDを消灯)         my_wait();                          // 適当に待ち時間を入れる     }

Best regards,

Yasuhiko Koumoto.

0 Kudos
Reply