SonicWave
Posts: 22
Joined: Mon Mar 19, 2018 1:10 pm

Problems with Mini-UART

Thu Mar 29, 2018 12:06 pm

This is my current code to get the mini-uart working:

Code: Select all

__attribute__ ((interrupt ("IRQ"))) void interrupt_irq(void)
{
    if(GET(TIMER_READ_IRQ)){
        if(led_on) {
            SET(GPCLR1, 1 << GPIO47);
            writeString("LED IS ON\n");
        }
        else {
            SET(GPSET1, 1 << GPIO47);
            writeString("LED IS OFFF\n");
        }
        led_on = !led_on;
        SET(TIMER_CLEAR_IRQ, 0);
    }
}

void writeString(char *str) {
    while(*str) {
        if((GET(AUX_MU_LSR_REG) & (1 << AUX_MU_LSR_REG_TRANS_EMPTY)));
            SET(AUX_MU_IO_REG,*str++);
    }
}

/*
 * ((250,000,000/460800)/8)-1 = 67 
 */ 
void initUART() {
    int ra;
    SET(AUX_EN_REG, 1 << AUX_EN_REG_ENABLE);
    SET(AUX_MU_IER_REG, 0);
    SET(AUX_MU_CNTL_REG, 0);
    SET(AUX_MU_LCR_REG, 3 << AUX_MU_LCR_REG_8BIT_MODE);
    SET(AUX_MU_MCR_REG, 0);
    SET(AUX_MU_IER_REG, 0);
    SET(AUX_MU_IIR_REG, 0xC6);
    SET(AUX_MU_BAUD_REG, 67);
    
    SET(GPFSEL1, (1 << GPIO14_GPFSEL_ALT5) | (1 << GPIO15_GPFSEL_ALT5));
    
    SET(GPPUD,0);
    for(ra=0;ra<150;ra++) asm volatile ("nop");
    SET(GPPUDCLK0,(1<<GPPUDCLK0_LINE14_CLK));
    for(ra=0;ra<150;ra++) asm volatile ("nop");
    SET(GPPUDCLK0,0);
    
    SET(AUX_MU_CNTL_REG, 1 << AUX_MU_CNTL_REG_ENABLE_TRANS);
}
But even though I am already useing three F in LED IS OFFF\n, I only get this from picocom:
LED IS ONLED IS OFLED IS ONLED IS OFLED IS ON
Neither the new line nor the second or third F are recognized. Why is that?

Schnoogle
Posts: 41
Joined: Sun Feb 11, 2018 4:47 pm

Re: Problems with Mini-UART

Thu Mar 29, 2018 4:33 pm

Hi SonicWave,

unfortunately I can only ask some questions and ask you to try things out:
1. did the string send correct outside your IRQ handler?
2. how is your IRQ handler triggered? Sometimes interrupts are re-entrent which means inside the IRQ-handler another or the same IRQ is raised again leading to another call. Try disabling IRQ's while starting your handler and enabling them right before you leave the handler
3. did you block writing to the UART so that no parallel startet stuff (e.g. from different cores) can interfere each other?
4. how does the "writeString" implementation look like? Are you re-using memory and have cahces enabled may also cause some weird things happens - at least in my experience ;)

BR Schnoogle

SonicWave
Posts: 22
Joined: Mon Mar 19, 2018 1:10 pm

Re: Problems with Mini-UART

Thu Mar 29, 2018 5:53 pm

Thanks for your answer.

I disabled the irq for testing purposes:

Code: Select all

void writeString(char *str) {
    while(*str) {
        if((GET(AUX_MU_LSR_REG) & (1 << AUX_MU_LSR_REG_TRANS_EMPTY)));
            SET(AUX_MU_IO_REG,*str++);
    }
}

/*
 * ((250,000,000/460800)/8)-1 = 67 
 */ 
void initUART() {
    int ra;
    SET(AUX_EN_REG, 1 << AUX_EN_REG_ENABLE);
    SET(AUX_MU_IER_REG, 0);
    SET(AUX_MU_CNTL_REG, 0);
    SET(AUX_MU_LCR_REG, 3 << AUX_MU_LCR_REG_8BIT_MODE);
    SET(AUX_MU_MCR_REG, 0);
    SET(AUX_MU_IER_REG, 0);
    SET(AUX_MU_IIR_REG, 0xC6);
    SET(AUX_MU_BAUD_REG, 67);
    
    SET(GPFSEL1, (1 << GPIO14_GPFSEL_ALT5) | (1 << GPIO15_GPFSEL_ALT5));
    
    SET(GPPUD,0);
    for(ra=0;ra<150;ra++) asm volatile ("nop");
    SET(GPPUDCLK0,(1<<GPPUDCLK0_LINE14_CLK));
    for(ra=0;ra<150;ra++) asm volatile ("nop");
    SET(GPPUDCLK0,0);
    
    SET(AUX_MU_CNTL_REG, 1 << AUX_MU_CNTL_REG_ENABLE_TRANS);
}

int main(void)
{
    initUART();
    
    while(1) {
        writeString("LED IS OFF\n");
        for(int i = 0; i < 250000; i++) asm volatile("nop");
    }
}
I get this from
picocom -b 460800 /dev/ttyUSB0
LED IS OFLED IS OFLED IS OF
4. how does the "writeString" implementation look like? Are you re-using memory and have cahces enabled may also cause some weird things happens - at least in my experience
As you can see in my code, I don't use memory or caches.
3. did you block writing to the UART so that no parallel startet stuff (e.g. from different cores) can interfere each other?
How do I do that?

Schnoogle
Posts: 41
Joined: Sun Feb 11, 2018 4:47 pm

Re: Problems with Mini-UART

Thu Mar 29, 2018 7:01 pm

Hi,

first of all, sorry that I did not look properly at the code :oops: ...
I do assume you set the baudrates on your terminal also to 57.600?
What also might be an issue is \n. Some terminals do not handle that properly I do use \r\n in my UART implementations when sending strings around...

Does your terminal that is recieving the UART data "mirroring" back what it gets? This would mean it tries to send back the recieved data to the UART which might interrupt RPi sending new data...

Other than this I do not see any obvious issue in your code, assuming that (1 << AUX_MU_LSR_REG_TRANS_EMPTY) equals to 0x20 ;)

Forget about the "blocking"... I'm using simple semaphores and in multicore-scenarios spinlocks to ensure only one thread/core is using the UART at a time, but that's nothing you need to worry about at this stage ;)

BR Schnoogle

SonicWave
Posts: 22
Joined: Mon Mar 19, 2018 1:10 pm

Re: Problems with Mini-UART

Thu Mar 29, 2018 7:22 pm

I do assume you set the baudrates on your terminal also to 57.600?
To 460.800
Some terminals do not handle that properly I do use \r\n in my UART implementations when sending strings around...
I tried that as well but it does not change anything.
Does your terminal that is recieving the UART data "mirroring" back what it gets? This would mean it tries to send back the recieved data to the UART which might interrupt RPi sending new data...
Even if it would - I did not connect the RX pin to my USB/UART converter.
assuming that (1 << AUX_MU_LSR_REG_TRANS_EMPTY) equals to 0x20
It does:

Code: Select all

#define AUX_MU_LSR_REG_TRANS_EMPTY      5
Where is the error? I don't see it? What is so different about *F* and *\r\n* that they don't show up.?

Schnoogle
Posts: 41
Joined: Sun Feb 11, 2018 4:47 pm

Re: Problems with Mini-UART

Fri Mar 30, 2018 11:24 am

Hi there,
I do assume you set the baudrates on your terminal also to 57.600?

To 460.800
well it seem I did the math wrong ;) - in this case the value passed to register AUX_MU_BAUD_REG need to be 66 instead of 67. You missed to subtract 1 based on the formula (core_clock_rate/(8*BAUD))-1 your current setting of 67 gives 459.558 which may cause the missing characters after some characters has been recieved correctly.... nevertheless from my experience the highest stable BUAD rate for RPi has been 115200.

Hope this helps

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 2 guests