|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24HJ256GP206 DMA RECEIVE |
Posted: Wed Jan 14, 2015 8:19 am |
|
|
Device: PIC24HJ256GP206
Compiler: 5.026
Hello,
I am currently transmitting UART1 data outbound through DMA and it's working well. The buffers are of varying length and everything is fine.
UART 1 is setup as 115200, N, 8, 1.
Now, I want to implement DMA reception on the same UART.
-> The data will be of variying length but no longer than 133 bytes;
-> The data can arrive at any time without notice;
-> The data will be processed once the entire data string has been received;
So far, I have the following (in different files):
.h file:
Code: | #BANK_DMA unsigned char DMAPacketRx[134]; |
.c interrupt file:
Code: |
#INT_DMA1
void INT_DMA_CH1( void )
{
// Whatever code needed here (if this interrupt handler is needed altogether)
}
#INT_RDA
void INT_SerialRX( void )
{
// Triggered on every character
}
|
.c main file:
Code: |
setup_dma( 1, DMA_IN_UART1, DMA_BYTE );
enable_interrupts( INT_DMA0 );
|
So now, I would guess that I need to start the DMA process somehow. If I use the DMA_START function, what parameters should I be using?
For the DMA transmission, I use the line below which enables me to send non-stop buffers of varying length and it works perfectly fine:
Code: |
dma_start( 0, DMA_ONE_SHOT | DMA_FORCE_NOW, &DMAPacket0[0], packetLength - 1 );
|
But in the case of data reception, I can't specify the packet length since I do not know the amount of data being received.
Of course I read through the CCS documentation and example but it is what it is... Not great.
Any help is greatly appreciated.
Thanks,
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Jan 14, 2015 9:04 am |
|
|
What you are describing can't really be done with DMA. How is the DMA controller ever going to know that a packet is complete?.
If there is an external signal saying 'this is a packet', then it can be done using this as the trigger. Without this, it is not a DMAable solution.
So, ignore DMA, and just code a receive interrupt. Use an interrupt buffer like EX_SISR (except do a search here for how to code this with non binary buffer sizes). Have your ISR do as little as possible, except whatever code is needed to detect that the packet is complete (looking for a particular marker byte etc..). Set a flag when this condition goes true. The data is then waiting in the buffer. If you prefer, you could use a linear buffer, and when the condition goes 'true', then use a memory to memory DMA transfer, to quickly leave the receive buffer waiting for the next packet.
How things work with DMA, is much better searched for in the MicroChip documentation. Only once you know 'what' you want to do, then look at the CCS manual to work out how this is done using CCS. Get 39742A from Microchip. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Jan 14, 2015 9:18 am |
|
|
Hi Ttelmah,
Thanks for the quick info. Yeah, after posting my message, I started thinking about it a bit and it didn't make sense.
So how do you actually use the DMA for UART reception? I'm confused right now. There _is_ such a thing as DMA_IN_UART1 but what is the purpose of it exactly?
I'm trying to wrap my head around the DMA RX concept and it's confusing.
Thanks again,
Benoit |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Jan 14, 2015 9:50 am |
|
|
DMA for UART reception only makes sense if the size of the packets is fixed. Further, if there is the possibility of noise corrupting the data stream, then this method gets less appealing.
I created a "bridge" card/project that we use to connect two distinct CAN networks using a dsPIC. Each dsPIC is at the center of 2 distinct CAN networks, and also supports two serial data links: one intended for a remote bridge and the other for a local SBC. The CAN networks use DMA and run at 250kbps, and the serial links run at 417kBaud (for the link to the other bridge) and 500kBaud (for the link to the SBC). I used DMA for the serial transmit but I couldn't justify/get my head around a way or reason to use DMA for the receive since the packets are random lengths. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Jan 14, 2015 10:36 am |
|
|
If your 'bus' has a 'this is a packet' line being sent as well, then DMA makes sense, or if the transfers are fixed size. Especially when high data rates are involved to perhaps a local card. I've used SPI receive like this (which is very similar), for a 256byte block, from another local device. That it allows you the time to not be handling byte by byte, is 'great', but then you have the downside of having to add timeout checking if a byte gets missed....
I can think of 'ingenious' ways of handling a variable length packet. If (for instance) there was an ETX at the end of the packet, you could add a 8pin PIC monitoring the data, to drop a line when this character is seen, then the transfer could automatically stop, and when the DMA interrupt is seen, the ETX has been received. Silly, but makes a point. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Jan 14, 2015 11:31 am |
|
|
Never thought of using a small dedicated PIC to monitor the RX data line to look for the end of packet character. That would work but unfortunately I'd need to design a new board to take advantage of it.
Definitely something to keep in mind for next time. |
|
|
|
|
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
|