Why does BME operation for GPIO causes the hard fault?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Why does BME operation for GPIO causes the hard fault?

ソリューションへジャンプ
865件の閲覧回数
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 解決策
674件の閲覧回数
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 返答(返信)
674件の閲覧回数
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 件の賞賛
675件の閲覧回数
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 件の賞賛