Error de interrupción anidado STM8, no descrito en la hoja de erratas actual ES019

3

Si el proceso principal ejecuta WFI con el bit AL establecido en CFG_GCR, el cambio de los bits de prioridad I1 / I0 en el ISR hace que la CPU se detenga cuando se produce una IRQ anidada.

Condiciones previas: todos los registros ITC_SPR1 tienen un valor predeterminado 0xFF.

Habilite TIM4 con generar interrupciones en el desbordamiento. ISR para TIM4 contiene solo el código para borrar el bit TIM_SR1_UIF en el registro TIM4_SR1. Desbloquee EEPROM para escritura, inicie el procedimiento de escritura de byte y habilite IRQ para completar la operación de escritura de EEPROM. En el ISR para EEPROM, elevar el nivel de IRQ mediante una instrucción RIM o especificar directamente los bits I1 / I0 mediante PUSH # 8, POP CC (por ejemplo) El programa principal establece el bit AL en el registro GCR y ejecuta la instrucción WFI.

Si en el EEPROM ISR, el nivel de IRQ generado por las instrucciones RIM o PUSH / POP CC y luego ocurrió el IRQ de TIM4, luego de que IRET del núcleo de TIM4 ISR esté bloqueado y el ISR de EEPROM no continúe.

Solución 1. Borre el bit AL en GCR antes de ejecutar la instrucción WFI en el bucle principal.

Solución 2. Borre el bit AL en GCR en EEPROM ISR antes de ejecutar las instrucciones RIM o PUSH / POP CC

Solución 3. Establezca el nivel de IRQ para EEPROM que no sea I1 = 1, I0 = 1 (por ejemplo, ITC- > ISPR1 = 0b11110111; antes de iniciar la operación de escritura de EEPROM).

No encontré este error en la hoja de erratas actual ES019.

Veo este error en la placa de descubrimiento STM8L con chip stm8l152c6t6. ¿Puede alguien reproducir este error en chips iguales o diferentes? Por favor, confírmalo o recházalo.

Ejemplo:

tim4ISR() {
    /* clear UIF */
    TIM4->SR1 &= (uint8_t)(~TIM_SR1_UIF);
}

eepromISR() {
    (void)FLASH->IAPSR; /* or other manner read IAPSR */

    /* Set some pin to indicate in-ISR state */

    __ASM("rim"); /* or __ASM("push #8\npop cc\n"); */

    /* delay into ISR */
    for(int i = 0;i < delayN;i++) ;

    /* clear AL for leave WFI after IRET and initiate next byte write */
    CFG->GCR &= ~CFG_GCR_AL;

    /* Clear some pin to indicate leave ISR */
}

main() {
    /* Set TIM4 for generate periodic IRQ */

    /* Unlock MASS */

    while(1) {
        /* Initiate EEPROM byte or word write operation */

        /* IRET stay on wait mode */
        CFG->GCR |= CFG_GCR_AL; 

       __ASM("wfi");
    }
}
    
pregunta Igor Nikolaev

0 respuestas

Lea otras preguntas en las etiquetas