Skip to main content
dherbst2
Associate
July 30, 2009
Question

UART 4 Problem

  • July 30, 2009
  • 6 replies
  • 1093 views
Posted on July 30, 2009 at 06:12

UART 4 Problem

    This topic has been closed for replies.

    6 replies

    st3
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    Are you sure UART4 is on APB1?

    dherbst2
    dherbst2Author
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    Im using UART4 on the STM32F103Ze.

    As soon as an UART4 RX Interrupt occurs, a hard fault exception occurs

    Hard fault Status Register = 0x40000000 (bit 30 is set)

    As far as I know this indicates one of the following faults:

    1. Bus fault,

    2. Memory management fault

    3. Usage fault

    Below is my code.

    UART initialization

    RCC->APB1ENR |= RCC_APB1Periph_UART4; //Enable clock for USART4

    UART4->BRR = 0x0EA6; //Set baudrate

    UART4->CR1 = 0x00000000; //Set Data, Stop bits & Flow control

    UART4->CR1 |= (USART_CR1_RE | USART_CR1_TE); //RX, TX enable

    UART4->CR1 |= 0x20; //RXNE Interrupt Enable

    UART4->CR1 |= USART_CR1_UE; //USART enable

    Interrupt initialization

    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    Interrupt

    void UART4_IRQHandler(void)

    {

    u8 Rx_Char;

    if(UART4->SR & USART_FLAG_RXNE) //RX Character

    {

    UART4->SR &= ~USART_FLAG_RXNE; //Clear interrupt flag

    Rx_Char = UART4->DR & 0xFF;

    UART4_Flag = 0xFF;

    }

    }

    I used the same code for USART1, 2 and 3, all working.

    andreas2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    Make sure that the address of UART4_IRQHandler is installed at the correct location in the vector table.

    dherbst2
    dherbst2Author
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    Hi St7

    According to the User Manual on p36, UART4 is on APB1.

    Is there something else that I am missing?

    Thanx

    st3
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    Quote:

    Ah, fuck, code tag doesn't work for this... code :p

    I know - it's pretty useless having a 'CODE' tag that doesn't actually work with source code, isn't it?!

    Who chose this forum software with such an obvious and fundamental flaw?!

    Previously noted nearly a year ago:

    http://www.st.com/mcu/forums-cat-7210-23.html

    [ This message was edited by: st7 on 30-07-2009 09:47 ]

    See also:

    http://www.st.com/mcu/forums-cat-8699-23.html

    [ This message was edited by: st7 on 30-07-2009 09:48 ]

    domen2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:19

    You could install a hard fault handler, maybe it'll provide some hint.

    ie. something like (made for GCC):

    void __attribute__ ((naked)) HardFaultException()

    {

    asm volatile (

    ''mov r1, #1\n\t''

    ''b generic_exception_handler\n\t''

    );

    }

    /*

    TST LR, #4

    ITE EQ

    MRSEQ R0, MSP

    MRSNE R0, PSP

    B hard_fault_handler_c

    */

    void __attribute__ ((naked)) generic_exception_handler()

    {

    asm volatile (

    ''tst lr, #4\n\t''

    ''ite eq\n\t''

    ''mrseq r0, msp\n\t''

    ''mrsne r0, psp\n\t''

    ''stmfd sp!, {r4-r11}\n\t''

    ''mov r2, sp\n\t''

    ''b generic_exception_handler_c\n\t''

    );

    }

    /* my precious debugging function

    * HardFault is triggered on ie. invalid memory access.

    * note: on IMPRECISERR, this doesn't help much. it just means that some

    * invalid access occured but possibly before (after/prediction?) PC

    */

    void generic_exception_handler_c(unsigned int *oldstack, int exception,

    unsigned int *newstack)

    {

    int oldstack_valid = (oldstack >= (unsigned int*)&_sdata && oldstack < newstack);

    volatile int ffs = 1;

    usart_setflag(USART_DEBUG, FLAG_DIRECT, 1);

    if (usart_getflag(USART_DEBUG, FLAG_ACTIVE))

    while (1);

    printf(''%s was caled, dumping regs:\n'', exception_strings[exception]);

    if (oldstack_valid) {

    printf(''r0\t0x%08x\t%i\n'', oldstack[0], oldstack[0]);

    printf(''r1\t0x%08x\t%i\n'', oldstack[1], oldstack[1]);

    printf(''r2\t0x%08x\t%i\n'', oldstack[2], oldstack[2]);

    printf(''r3\t0x%08x\t%i\n'', oldstack[3], oldstack[3]);

    } else {

    printf(''sp\t0x%08x\t%i\n'', (unsigned int)oldstack, (unsigned int)oldstack);

    printf(''sp is invalid, so some registers are missing\n'');

    }

    printf(''r4\t0x%08x\t%i\n'', newstack[0], newstack[0]);

    printf(''r5\t0x%08x\t%i\n'', newstack[1], newstack[1]);

    printf(''r6\t0x%08x\t%i\n'', newstack[2], newstack[2]);

    printf(''r7\t0x%08x\t%i\n'', newstack[3], newstack[3]);

    printf(''r8\t0x%08x\t%i\n'', newstack[4], newstack[4]);

    printf(''r9\t0x%08x\t%i\n'', newstack[5], newstack[5]);

    printf(''r10/sl\t0x%08x\t%i\n'', newstack[6], newstack[6]);

    printf(''r11/fp\t0x%08x\t%i\n'', newstack[7], newstack[7]);

    if (oldstack_valid) {

    printf(''r12/ip\t0x%08x\t%i\n'', oldstack[4], oldstack[4]);

    printf(''sp\t0x%08x\t%i\n'', (unsigned int)oldstack, (unsigned int)oldstack);

    printf(''lr\t0x%08x\t%i\n'', oldstack[5], oldstack[5]);

    printf(''pc\t0x%08x\t%i\n'', oldstack[6], oldstack[6]);

    printf(''psr\t0x%08x\t%i\n'', oldstack[7], oldstack[7]);

    }

    printf(''CFSR\t0x%08x\n'', *(unsigned int*)0xe000ed28);

    printf(''HFSR\t0x%08x\n'', *(unsigned int*)0xe000ed2c);

    printf(''DFSR\t0x%08x\n'', *(unsigned int*)0xe000ed30);

    printf(''MMAR\t0x%08x\n'', *(unsigned int*)0xe000ed34);

    printf(''BFAR\t0x%08x\n'', *(unsigned int*)0xe000ed38);

    printf(''AFSR\t0x%08x\n'', *(unsigned int*)0xe000ed3c);

    printf(''\nhalted\n'');

    while (ffs)

    ;

    }

    Ah, fuck, code tag doesn't work for this... code :p