View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
Anyone used the SPI DMA with 18F26J11 (or similar)? |
Posted: Thu Nov 18, 2010 2:36 pm |
|
|
I recently started using the PIC18F26J11 parts in many of my small projects. It is a great chip and is very flexible.
I noticed it has a DMA associated with the SPI port. This sounds like it would be useful in getting data blocks into and out of an SD card attached as an SPI peripheral.
Has anyone used this feature with this (or similar) chips? If so, would you mind sharing code for setting it up?
It doesn't appear the V4.114 PCWHD compiler has any functions for setting this feature up.
Thanks. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Nov 18, 2010 7:13 pm |
|
|
I've used the 26/46j11 in a few things -- it's a nice chip.
On SPI DMA, I have not. I was just looking at it again last night.
Considering that 1024bytes is all it will xfer at a time and that's 2 SD sectors... that could be handy... Yes it could....
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Nov 19, 2010 2:46 am |
|
|
I use the SPI DMA on the 18F46J50 for reading and writing to SD card. It works very well. Below are my DMA routines but you will have to modify them to suit your application.
Not many comments I am afraid
Code: |
// spi_dma.h
//
#ifndef SPI_DMA_H
#define SPI_DMA_H
// SPI mode definitions.
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H | SPI_SAMPLE_AT_END)
#define SPI_MODE_2 (SPI_H_TO_L | SPI_XMIT_L_TO_H | SPI_SAMPLE_AT_END)
#define SPI_MODE_3 (SPI_H_TO_L)
// Definitions for SPI2
#byte SSP2STAT = 0x0F73
#byte SSP2BUF = 0x0F75
#byte SSP2CON1 = 0x0F72
// Definitions for SPI DMA transfer
#byte DMACON1 = 0x0F88
#byte DMACON2 = 0x0F86
#byte TXADDRH = 0x0F6A
#byte TXADDRL = 0x0F6B
#byte RXADDRH = 0x0F68
#byte RXADDRL = 0x0F69
#byte DMABCL = 0x0F67
#byte DMABCH = 0x0F66
// DMACON1 bits
#bit SSCON1 = DMACON1.7
#bit SSCON2 = DMACON1.6
#bit TXINC = DMACON1.5
#bit RXINC = DMACON1.4
#bit DUPLEX1 = DMACON1.3
#bit DUPLEX0 = DMACON1.2
#bit DLYINTEN = DMACON1.1
#bit DMAEN = DMACON1.0
// DMACON1 defines
#define DMA_SSCON1 0x80
#define DMA_SSCON2 0x40
#define DMA_TXINC 0x20
#define DMA_RXINC 0x10
#define DMA_DUPLEX1 0x08
#define DMA_DUPLEX0 0x04
#define DMA_DLYINTEN 0x02
#define DMA_DMAEN 0x01
int1 dma_write = false;
int1 dma_busy = false;
int8 res1, res2;
void dma_init(void);
void dma_write_block(int16 addr);
void dma_read_block(int16 addr);
#endif
|
Code: |
#include "sdcard.h"
#include "spi_dma.h"
#INT_SSP2
void spidma_isr(void)
{
int8 timeout;
timeout = 10;
if (!DMAEN)
{
disable_interrupts(INT_SSP2);
// If write mode
if (dma_write)
{
spi_write2(0xFF); // 16 bit CRC MSB (ignored)
spi_write2(0xFF); // 16 bit CRC LSB (ignored)
do
{
res1 = spi_read2(0xFF);
} while((res1 == 0xFF) && (timeout--));
do
{
res2 = spi_read2(0xFF);
} while(res2 == 0x00);
bank_full = false;
}
else
{
spi_read2(0xFF); // 16 bit CRC MSB (ignored)
spi_read2(0xFF); // 16 bit CRC LSB (ignored)
// spi_read2(0xFF); // Dummy ?
bank_full = true;
}
// output_high(PIC_SD_CS); // De-select SD Card
dma_busy = false;
}
}
void dma_init(void)
{
DMACON1 = DMA_TXINC | DMA_RXINC | DMA_DUPLEX0;
DMACON2 = 0x00;
}
void dma_write_block(int16 addr)
{
dma_write = true;
dma_busy = true;
DMACON1 = DMA_TXINC | DMA_DUPLEX0;
DMACON2 = 0x0F;
TXADDRH = make8(addr, 1);
TXADDRL = make8(addr, 0);
DMABCH = 0x01; // 512 byte count High
DMABCL = 0xFF; // 512 byte count Low
enable_interrupts(INT_SSP2);
DMAEN = true; // Start DMA transfer
}
void dma_read_block(int16 addr)
{
dma_write = false;
dma_busy = true;
DMACON1 = DMA_RXINC;
DMACON2 = 0x0F;
RXADDRH = make8(addr, 1);
RXADDRL = make8(addr, 0);
DMABCH = 0x01; // 512 byte count High
DMABCL = 0xFF; // 512 byte count Low
enable_interrupts(INT_SSP2);
DMAEN = true; // Start DMA transfer
}
|
before calling these routines I get the SD card ready for transfer by sending the relevant command. These routines will then set the DMA to read/write 512 bytes and then interrupt to signal that it has finished.
Hopw it helps. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Fri Nov 19, 2010 12:05 pm |
|
|
Thanks very much for posting this.
Very helpful! |
|
|
|