Jump to content
 
  • 0
dvvrao

MPLAB Harmony Configuration Settings for UART Higher Baud rates - PIC32MX470512L

Question

Originally the problem is posted at: https://www.microchip.com/forums/m1092099.aspx#1092358

I could not upload the screenshots of the MHC Settings there in that forum due to file size limitations.

So, I am using this forum. I am uploading files here and use this web link there... to point to attached files...

Thanks for that!

The question is:

I am trying to operate the UART with higher baud rates. The PIC32 Micro controller used is PIC32MC470F512L. I use MPLAB Harmony. The UART is configured  in loop back mode. I wrote a program to send and receive data. The program works well up to baud rate of 4915200 (approx 5Mbps). The same program does not work for baud rates greater than 4915200. I configured clock scheme such that the PBCLK is 96MHz.
 
Please suggest, if i need to do some more settings using MPLAB Harmony Configurator.
 
Due to file size limitation, I am unable to upload the "package" form of the MPLAB X Project.

MHC_Settings.zip

Share this post


Link to post
Share on other sites

16 answers to this question

Recommended Posts

  • 0

According to your zip package, PBCLK is set to 48 MHz, not 96MHz? And it's a PIC32MX470F512L, just for clarity 🙂

It would be a good idea to debug your project and have a look at the actual register settings, to see if Harmony did everything right. I would also suggest to check the analog output signal with a scope to check the frequency and the signal quality. Is there a signal at higher baud rates and how does it look like?

 

 

  • Helpful 1

Share this post


Link to post
Share on other sites
  • 0

Yes you Peripheral clock is definitely 48MHz which means with a BRGH=1 you will only be able to go up to 6MHz, if you change the clock to 96MHz you can generate up to 12MHz  BUT you should beware that when you have BRGH=1 the formula is dividing by 4 becuase the oversampling clock is only running at 4x and this can be notoriously unreliable.

For more details see this discussion, in summary if you oversample 16x it leaves you with an error budget of 2.03%. When you over sample only 4x the error budged narrows to 0.52% and achieving that accuracy means you will have to drive the lines pretty hard to reduce the slew rate and also match the impedance to prevent ringing if you want to communicate reliably!

BTW. note that I used a 10% rise time and fall time for that calculation in the discussion. At a baud rate of 12MHz that means a rise time of 8.3ns, and at 24MHz you will be down to 4.15ns of allowed rise and settling time on the line to sample it accurately. Better use a scope to check if your full system can achieve this, if not you will be able to send but you will not be able to receive successfully.

 

 

 

 

  • I Agree 1

Share this post


Link to post
Share on other sites
  • 0

I want to operate the UART of PIC32MX470512L with supported maximum data rate (Baud Rate). With MPLAB Harmony I could configure the PBCLK = 96 MHz (not in the attached project file).

There is formula in the reference manual like below:

Baud Rate = (FPB / (4 * (UxBRG + 1))); when bit BRGH = 1.

FPB = Frequency Peripheral Bus => PBCLK = 96 MHz

UxBRG = Baud Rate Register

As per this formula the maximum supported Barate Rate would be 24MHz (FPB/4, when UxBRG = 0).

Upto 8MHz the UART is able to receive data. I did not validate the received data. But after 8MHz the UART is able to send but not able to receive. So, I was asking if I need to do any other settings in Harmony to achieve the supported maximum baud rate???

As suggested by ORUNMILA I have to check for signal quality in Oscilloscope. I will do that and come back.

 

Share this post


Link to post
Share on other sites
  • 0
On 3/29/2019 at 8:21 AM, Orunmila said:

Yes you Peripheral clock is definitely 48MHz which means with a BRGH=1 you will only be able to go up to 6MHz, BUT you should be very careful about using BRGH=1 which has only 4x oversampling as this can be notoriously unreliable.

See this discussion for the detailed calculations, but in summary if you oversample 16x it leaves you with an error budget of 2.03%. When you sample only 4x oversampling the error budged narrows to 0.52% and achieving that accuracy means you will have to drive the lines pretty hard to reduce the slew rate and also match the impedance to prevent ringing if you want to communicate reliably!

BTW. note that I used a 10% rise time and fall time for that calculation in the discussion. At a baud rate of 12MHz that means a rise time of 8.3ns, and at 24MHz you will be down to 4.15ns of allowed rise and settling time on the line to sample it accurately.

 

 

 

Hi Orunmila,

BRGH is a bit named "High Baud Rate Enable bit" in the register named "UARTx Mode Register". So it can have values either '0' or '1'. 

When PBCLK (Peripheral Bus Clock) is 48MHz and BRGH Bit is '1' then the formula for Baud Rate is " (FPB / (4 * (UxBRG + 1))) ". FPB = Frequenct Peripheral Bus, UxBRG = Baud Rate Register. So, we can get maximum baud rate when "UxBRG = 0" and the value will be:

48MHz/(4 * (0 + 1) = 48MHz/4 = 12Mbps.

So, with PBCLK of 48 MHz the maximum Baud Rate of 12Mbps should be possible.

At 12Mbps Baud Rate one PIC32MX Microcontroller is able to transmit but not able to receive.

1. I want to know if the problem is with configuring any registers?

2. Any problem with interfacing the 2 PIC32MX microcontrollers? Can I connect 2 UARTS on different micro-controller boards using jumper wires? Does the length of jumper wires matter? Is it advisable to to connect 2 UARTS at 3.3 level? Is USB power suppy sufficient to operate UART at this baud rate?

By the way my hardware is:

1. PIC32 USB Starter Kit III (https://www.microchip.com/DevelopmentTools/ProductDetails/dm320003-3)

2. Starter Kit I/O Expansion Board (https://www.microchip.com/DevelopmentTools/ProductDetails/dm320002)

I power the board using USB cable connecting to PC.

Share this post


Link to post
Share on other sites
  • 0

Not every pin is capable of driving such high frequencies. I strongly suggest to have a look at the output signal with a scope. Are the edges of the signal okay or do they get rounder and rounder with increasing baud rate? Is the frequency correct? A few pins may have special hardware (such as SPI) to have more drive strength, have a Schmitt trigger behavior for inputs etc.

Share this post


Link to post
Share on other sites
  • 0
13 hours ago, dvvrao said:

BRGH is a bit named "High Baud Rate Enable bit" in the register named "UARTx Mode Register". So it can have values either '0' or '1'. 

Sorry @dvvrao, I have edited my answer to make it more clear. When you set that bit the behavior of the uart is changed from a 16x oversampling clock to a 4x oversampling clock. 

Share this post


Link to post
Share on other sites
  • 0

About your other questions.

yes you can connect between devices on 3V3 just fine like that but you have to always be careful when you are driving at such a high frequency as the inductance and capacitance of the wires (and of course the length) will tend to filter out your signal, so always look at the signal quality with a scope so you know what you are dealing with!

Share this post


Link to post
Share on other sites
  • 0

I am yet to analize the signal in scope, Meanwhile I did some experiemnetation. I sent one byte at a time, it is received properly at the other end, even at 24Mbps baud rate. But when I sent continous stream of bytes then there is problem even with baud rate of 9600. I am guessing there is problem with UART Device Driver that I use that comes with Harmony. I use "USART Dynamic Driver Library with Buffer Queue data transfer model with DMA.

Please have a look here "http://microchipdeveloper.com/harmony:drv-usart-dynamic on "USART Dynamic Driver Library"

Share this post


Link to post
Share on other sites
  • 0

Perhaps you can post your code here? Typically UART's fail due to framing errors or overrun errors not being handled correctly ...

Share this post


Link to post
Share on other sites
  • 0

Today, I tried to debug the issue further. I found that there is Overrun Error. This error is present at lower baud rates like 9600 also. Due to this error, at the receiving end, few data bytes are received and then the UART does not receive data further. 

After using the API "USART_ReceiverOverrunErrorClear_Default()" the UART does not stop receiving data when Overrun Error occurs. But still received data is erroneous. So, at the transmission end added a delay of few milli seconds. With the addition of delay, no errors are seen. The receiving works at baud rate of 24Mbps also.
 
Please suggest, the way to overcome/handle the overrun errors.
 

PFA the latest code.

The zip file contains 2 MPLAB X IDE projects in the form of packages.

The transmit code is in the file "uarttransmit". This code continuously transmit a byte. Uses UART1.

The receive code is in the file "uartreceive". This code continuously receives a byte. Uses UART1. And prints "Success" on UART2 is expected data byte is received, otherwise prints "Error" and the hex value of data byte received.

code_9April2019.zip

Share this post


Link to post
Share on other sites
  • 0

Hi All,

Did anyone get a chance too see my code?

Thanks & Regards,

Vishnuvardhan

Share this post


Link to post
Share on other sites
  • 0

Today I tried the following:

- Increased the number of buffers (from 1 to 10) to receive the data from UART Driver. UART Dynamic Driver - Buffer Queue Data Transfer Model with DMA. This driver code is generated by Harmony.

- With this modification, I sent 5K Bytes in a burst. At the receiving end all the bytes are received correctly.

But, if I remove the call to function "USART_ReceiverOverrunErrorClear_Default()" then the receiving program stops after receiving few bytes.

 

PFA the latest code file.

 

Can anyone please look into the code to check what could be the problem?

 

app.c

Share this post


Link to post
Share on other sites
  • 0

I can try and take a look later today, can you please attach your latest project as exported from MPLAB as a package zip?

Share this post


Link to post
Share on other sites
  • 0

Ok I had a look, boy is that a lot of complex code to do such a simple thing! 

I have some questions for you. You say that with the modification you received all of the bytes correctly, but without the call to clear the overrun the reception stops after getting only a few bytes?

This seems very strange because the overrun error should only have an effect if an actual overrun happened on the uart, and if that happened you would have lost at least one byte of data???

Like I said there is a lot of code and if you are running at a high baud rate you have to ensure that you have enough time in the worst case scenario to receive data at full speed without dropping any characters. This means your entire state machine must be able to go through a full cycle at least once per character, but likely twice as it may pass the check for the next byte just before it arrives, so you need to make sure you can cycle through everything in time. The easiest way to test this is toggle a pin only in your app state machine, you know it goes through 3 states every cycle deterministically, so just time with a scope how long this takes, take this time and multiply by 2 and that will be your maximum byte period.

Now remember if you have the clock on 96MHz and you are trying to receive at 24Mbps that would mean 2.4 Mbyte/s (as uart has 1 start and 1 stop abd 8 data bits = 10total). That would give you only 96/24 = 40 instructions to cycle through the entire loop for each byte received. 

Looking at the code this does not seem to be possible, so you should run behind and loose data, getting overruns, which if you do not clear the error will disable the UART, as you are seeing.

I would have said I am certain that this is what is happening, but you say you could receive 5kb of data without any error which seems almost unbelievable to me if you were running at such a high baud rate (of course you did not specify what speed you were running the test at?)

You can usually buy some time and process data much faster by reading more than 1 byte at a time. If you make your buffer 100 bytes and every cycle read as many bytes as you can it should be possible to speed up the processing by more than 10x as the code now only has to do a tight loop to copy the data out (perhaps 5/6 instruction cycles) instead of an entire loop through the main state machine (hundreds of cycles) for every byte.

Can you please take the measurements I suggested and tell me how are you checking if you received all 5kb correctly, because I still find that hard to believe.

Share this post


Link to post
Share on other sites
  • 0

Hi Orunmila,

Thanks for the reply!

I understood your analysis and suggestions. I will do the same and comeback with results.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


 


×
×
  • Create New...