Why does BME operation for GPIO causes the hard fault?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Why does BME operation for GPIO causes the hard fault?

跳至解决方案
1,076 次查看
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 项奖励
回复
1 解答
885 次查看
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 项奖励
回复
2 回复数
885 次查看
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 项奖励
回复
886 次查看
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 项奖励
回复