CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

dpics33 uart2 DMA

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

dpics33 uart2 DMA
PostPosted: Wed Jul 09, 2014 3:52 pm     Reply with quote

Hello!

I am using the UART2 module on a dspic33fj32gp302
and I need to receive 8 bytes with DMA.

I already tested that the UART is receiving properly by polling the URXDA bit (U2STA.0) and then reading the U2RXREG.

When I use DMA, the DMA interrupt triggers when the correct number of bytes is received but the contents of the DMA buffer is garbage.


Code:

#BANK_DMA
    char UART2BUF[8];


#INT_DMA0
void DMA0_ISR(void){

 //code to display the buffer contents...

}



Code:

    setup_dma(0, DMA_IN_UART2, DMA_BYTE);
    dma_start(0, DMA_CONTINOUS, &UART2BUF[0] );   

    enable_interrupts(INT_DMA0);


I also tried to manually fill the buffer with known values just to check my "code to display the buffer contents" code.


It looks like the address of the buffer is wrong?

Please give me your opinions.

Thanks.

compiler 4.134 (even though I tried older versions too)
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 3:00 pm     Reply with quote

Make sure the compiler is setting bits 7, and 6 on U2STA to zero. It sounds as if it is (otherwise the interrupt wouldn't occur at the required place), but if this is wrong corrupted data will occur.
Double check the errata. I don't think any apply to this (unless you are using two stop bits).
Does it work on UART1?.
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 5:32 pm     Reply with quote

Hello!

bits 6 and 7 of U2STA are 0.
The same problem appears with UART1.

The interrupt occurs but the buffer never gets updated with incoming data.

During initialization I fill the buffer with data:

Code:

for(i=0;i<8;++i) UART2BUF[i]=65;  //ASCII 'A'


and when the interrupt occurs and I read the buffer I get all 'A' which means that the buffer is never updated.

I am pretty sure it is an address problem. Maybe it is because of the dspic33fj32gp302. I remember trying something similar with a dspic33fj64gp802 and it worked. I guess I have to change the PIC and try.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 1:30 am     Reply with quote

Try using the standard C shortcut for the array address:

dma_start(0, DMA_CONTINUOUS, UART2BUF);

I'd really suspect it is a version problem with your compiler(s). 4.134, is an old version, and it sounds as if the other's you have tried are older still...

I didn't keep the versions around this point, as a lot of problems seemed to appear, especially with the DsPIC.

Look at the .sym file (or use the symbol option in the IDE), and verify it is placing UART2BUF in the area above address 0x1400 (where DMA RAM starts). it could be just a slip in the device database, and it 'thinks' the RAM is somewhere else....

Running on a later compiler (4.141), it correctly places UART2BUF at address 0x1400, and loads the DMA0STx registers with 0 (to access the first bytes in this area).

I notice one 'oddity'.

Have 4.137 (fractionally later than your compiler), and one version a little older. 4.137, correctly loads DMACNT with 7. The older compiler loads it with 8. This means it'd try to transfer 9 bytes not 8, into an 8 byte array....

The current compilers all put the same values in the registers as 4.137

So I then 'bodged':
Code:

#include <main33dma.h> //your fuses etc.

#BANK_DMA
    char UART2BUF[7];
#BANK_DMA
    char dummy; //reserve one extra byte to allow 8 values.
   
#INT_DMA0
void DMA0_ISR(void)
{
   //code to display the buffer contents...
}

void main(void)
{
   int i;
   setup_dma(0, DMA_IN_UART2, DMA_BYTE);
   dma_start(0, DMA_CONTINOUS, UART2BUF);   
   enable_interrupts(INT_DMA0);

   for(i=0;i<8;++i) UART2BUF[i]=65;  //ASCII 'A'

   while (TRUE) ;
}

This results in the registers being loaded with the same values as the current compiler. It's a real 'nasty', since one is declaring a 7 element array, and then writing 8 elements to it, but it'd be worth trying and seeing if this changes anything.....
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 7:34 am     Reply with quote

I'd also suggest "manually" setting registers to see what happens as opposed to trusting the CCS functions. I've developed 3 different products in the last 2 years, all using the same dsPIC, all heavily using DMA. I used v4.141 of the compiler. Although I didn't actually try the CCS DMA functions, I did try their stock CAN code and quickly regretted it.
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 8:35 am     Reply with quote

from the .sym file:

Code:

F36-F37 log.data2
F36.1   atan.flag
F38-F39 log.p
F3A-F3B log.n
F3E-F45 ceil.x
F3E-F45 floor.x
F56-F5D CEIL_FLOOR.x
F5E     CEIL_FLOOR.n
F5F.0   CEIL_FLOOR.s
F60-F67 CEIL_FLOOR.y
F68-F6F CEIL_FLOOR.res
F70-F77 CEIL_FLOOR.l
1380-13FF Stack
1400-1407 UART2BUF

ROM Allocation:
3092  @DIV3232B
0480  SetupADC
0348  @delay_ms1
3936  @MULFF
07C8  @SITOF
08DC  @ADDFF
0812  @DIVFF
062C  atoi
0E26  @MULFF64
0BD4  @SI64TOF64


UART2BUF is on the right address and occupies correct space 1400-1407 (8 bytes)

I also tried ccs v5.003. The result is the same.

How can I check that DMA0STx registers gets the correct value 0 (to access the first bytes in this area)?
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 8:53 am     Reply with quote

With 5.003, I'd expect it to not work. There was a bug with interrupt handling on the early V5 releases.
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 9:17 am     Reply with quote

I think I already wasted too much time on ccs bugs.

I will just use a second pin as a RTS handshake to receive data when needed. I just wanted to avoid that and have the system handle it automatically. Thanks for the support guys!

If anything comes in mind please drop a line ;)
_________________
George.
jeremiah



Joined: 20 Jul 2010
Posts: 1321

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 11:05 am     Reply with quote

Back some months ago, I remember someone else having issues with DMA and UART on a similar chip. The end result was that the documentation on the dma_start() method was not up to date and they needed to do something with the 4th optional parameter for that method for it to work.

I don't remember how related it was to your issue, but it might be worth checking out. I believe the thread occurred in Feb or March time frame, so a forum search for dma should give you a good starting point.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Sat Jul 12, 2014 3:37 am     Reply with quote

Yes. That was the thread at:
<http://www.ccsinfo.com/forum/viewtopic.php?t=51920&highlight=pic+dma>

It was slightly more complex, since the poster was wanting to do a transfer smaller than the buffer. However the same fix would work for the incorrect setting used in the older compilers, using the third parameter to correctly set the size.

Best Wishes
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 2:19 am     Reply with quote

I've had a little play.

Have you got a #use RS232 statement?.

Problem is that unless you have this, the UART baud rate is not programmed.

You also need the #PIN_SELECT statements to program the pins to be used.

So I added:
Code:

#PIN_SELECT U2RX = PIN_B2
#PIN_SELECT U2TX = PIN_B3 //set these to suit your UART
#use RS232(UART2,STREAM=UART2,BAUD=115200,STREAM=U2)

//and
   setup_uart(115200,U2);
   dma_start(0, DMA_CONTINOUS, UART2BUF, 7); 

The latter line corrects the size error with the older compilers.
The setup_uart line I added, since it seems as if the optimiser may not actually configure the UART, if there are not getc/putc lines in the code.
With this done, running on a sim, I seem to be getting a sensible result.
Only though if I use DMA for the transmit as well, and add an error interrupt for the UART.
This may relate to:
<http://www.microchip.com/forums/m706242.aspx>

I suggest also, you switch to ping_pong mode. With your current setup, and your relatively slow CPU clock, if the baud rate is high, there may be problems if you don't get into/out of the DMA interrupt quickly, with the data safely saved.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group