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 CCS Technical Support

Anyone used the SPI DMA with 18F26J11 (or similar)?

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



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

Anyone used the SPI DMA with 18F26J11 (or similar)?
PostPosted: Thu Nov 18, 2010 2:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 18, 2010 7:13 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 2:46 am     Reply with quote

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 Smile

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

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 12:05 pm     Reply with quote

Thanks very much for posting this.

Very helpful! Very Happy
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