EmbDev.net

Forum: ARM programming with GCC/GNU tools SAM&S256 - DBGU_UART


von Marcin D. (marcind)


Rate this post
useful
not useful
Hi!

I have a problem with uart - when I send text I get uncorrect chars.

void dbgu_init()
{

  AT91S_DBGU *pDBGU = AT91C_BASE_DBGU;

  //enable pins
  *AT91C_PIOA_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;



  pDBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX |
                         AT91C_US_RXDIS |   AT91C_US_TXDIS;

        pDBGU->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL;

         pDBGU->DBGU_BRGR = 78;       /* Baud Rate = 38400 */

   pDBGU->DBGU_CR = AT91C_US_RXEN  | AT91C_US_TXEN;
}

int dbgu_putc( int ch)
{

  while (!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY));
  return (AT91C_BASE_DBGU->DBGU_THR = ch);
}

void dbgu_puts(char* s)
{
  while ( *s ) dbgu_putc( *s++);
}

in main():
dbgu_init(); and dbgu("text");

On terminal I get in hex:
0xF8 0x1E 0x31
After reset received chars are diferent.

What's wrong??

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Marcin Domaszewicz wrote:
>          pDBGU->DBGU_BRGR = 78;       /* Baud Rate = 38400 */

Double-check if this value really is valid for the desired "38400
baud-rate" with the configured frequency (clock-source, PLL etc.).

von Marcin D. (marcind)


Rate this post
useful
not useful
Thanks for answer.

I have MCK = 47923200 so after divided by 16 and 38400 I get 78.
I use USART0 with this parameter and it works OK.

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
You might look into the AT91SAM7S-EK software-package available from
atmel.com. I have just used dbgu.h/dbgu.c from the package for the
SAM7SE-EK in a project with an AT91SAM7SE512 and it worked as expected.
Some excerpts follow but it might be better to get the original-code
from the Atmel site.

//...
#define BOARD_MCK               48000000
//...
#define DBGU_STANDARD           AT91C_US_PAR_NONE
//...

int main(void)
{
//...PIO-configuration...
   DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK);
//...send chars/strings using DBGU_PutChar


copied from the software-package's code:

void DBGU_Configure(unsigned int mode,
                           unsigned int baudrate,
                           unsigned int mck)
{
    // Reset & disable receiver and transmitter, disable interrupts
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
    AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF;

    // Configure baud rate
    AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16);

    // Configure mode register
    AT91C_BASE_DBGU->DBGU_MR = mode;

    // Disable DMA channel
    AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;

    // Enable receiver and transmitter
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;
}

static void DBGU_PutChar(unsigned char c)
{
    // Wait for the transmitter to be ready
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);

    // Send character
    AT91C_BASE_DBGU->DBGU_THR = c;

    // Wait for the transfer to complete
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);
}

von Marcin D. (marcind)


Rate this post
useful
not useful
I try to use Atmel code but it still doesn't work.

The only change I do I replace a line:

>     // Reset & disable receiver and transmitter, disable interrupts
>     AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;

with

pDBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX |
                         AT91C_US_RXDIS |   AT91C_US_TXDIS;

and also I wrote

//enable pins
  *AT91C_PIOA_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;

von Marcin D. (marcind)


Rate this post
useful
not useful
Hi
I managed to run DBGU uart but still I have a problem because sometimes
chars are wrong, espacially when rate is high. When it is 4800 bps,
there are 20% of error. It is probably connected with wrong clocking,
but I can't find what is wrong.

Please for help


The code is:

AT91S_DBGU *pDBGU = AT91C_BASE_DBGU;

/// Initialize Serial Interface
void dbgu_init( unsigned int baudrate)
{
  //enable clock
  AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, ( 1 << AT91C_ID_SYS ) )
;
  //enable RxD and TxD pin
  *AT91C_PIOA_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;


  pDBGU->DBGU_CR = AT91C_US_RSTRX |          /* Reset Receiver      */
          AT91C_US_RSTTX |          /* Reset Transmitter   */
          AT91C_US_RXDIS |          /* Receiver Disable    */
          AT91C_US_TXDIS;           /* Transmitter Disable */


  pDBGU->DBGU_IDR = 0xFFFFFFFF;

  pDBGU->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL | 0 << 15;


  pDBGU->DBGU_BRGR = AT91F_US_Baudrate(MCK,baudrate);
/* Baud Rate Divisor */

    // Disable DMA channel
  pDBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;

  pDBGU->DBGU_CR = AT91C_US_RXEN  |          /* Receiver Enable     */
          AT91C_US_TXEN;            /* Transmitter Enable  */

}

void dbgu_isr(unsigned int int_type)
{

  AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,AT91C_ID_SYS,0,0,ISR_Dbgu);
  AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_SYS);
  pDBGU->DBGU_IER = int_type;
}

The interrupt occurs when char is received and works as simple echo.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.