/*
PIC18F24J11 DMA driver
File : spi_dma_PIC18F24J11.h
Creator : Eduardo Guilherme Brandt
Contributor : Gerardo Daniel Cibeira
Created : 31/01/2012 (v1.0)
Contact : eduardogbrandt@yahoo.com.br
Historic : Version 1.0 - 31/01/2012 Eduardo Guilherme Brandt
Version 1.1 - 19/05/2014 Gerardo Daniel Cibeira
*/
#ifndef SPI_DMA
#define SPI_DMA
/***************************
Further information
- I/O PIN CONSIDERATIONS
When enabled, the SPI DMA module uses the MSSP2 module. All SPI related input and output signals related
to MSSP2 are routed through the Peripheral Pin Select module.
- RAM TO RAM COPY OPERATIONS
Although the SPI DMA module is primarily intended to be used for SPI communication purposes, the module
can also be used to perform RAM to RAM copy operations.
To do this, configure the module for Full-Duplex Master mode operation, but assign the SDO2 output
and SDI2 input functions onto the same RPn pin in the PPS module. This will allow the module to operate in
Loopback mode, providing RAM copy capability.
- IDLE AND SLEEP CONSIDERATIONS
The SPI DMA module remains fully functional when the microcontroller is in Idle mode.
During normal sleep, the SPI DMA module is not functional and should not be used. To avoid corrupting a
transfer, user firmware should be careful to make certain that pending DMA operations are complete by
polling the DMAEN bit in the DMACON1 register prior to putting the microcontroller into Sleep.
In SPI Slave modes, the MSSP2 module is capable of transmitting and/or receiving one byte of data while in
Sleep mode. This allows the SSP2IF flag in the PIR3 register to be used as a wake-up source. When the
DMAEN bit is cleared, the SPI DMA module is effectively disabled, and the MSSP2 module functions
normally, but without DMA capabilities. If the DMAEN bit is clear prior to entering Sleep, it is still possible to
use the SSP2IF as a wake-up source without any data loss.
Neither MSSP2 nor the SPI DMA module will provide any functionality in Deep Sleep. Upon exiting from
Deep Sleep, all of the I/O pins, MSSP2 and SPI DMA related registers will need to be fully reinitialized before
the SPI DMA module can be used again.
*/
// Definitions for SPI DMA transfer
#byte DMA_TXADDRH = 0x0F6A //SPI DMA Tranmsit Data Pointer High Byte ---- 0000 73
#byte DMA_TXADDRL = 0x0F6B //SPI DMA Tranmsit Data Pointer Low Byte 0000 0000 73
#byte DMA_RXADDRH = 0x0F68 //SPI DMA Receive Data Pointer High Byte ---- 0000 73
#byte DMA_RXADDRL = 0x0F69 //SPI DMA Receive Data Pointer Low Byte 0000 0000 73
#byte DMA_DMABCH = 0x0F66 //SPI DMA Receive Data Pointer High Byte
#byte DMA_DMABCL = 0x0F67 //SPI DMA Byte Count Low Byte 0000 0000 73
// Definitions for SPI DMA transfer
#byte DMA_DMACON1 = 0x0F88 //see DMACON1. DMA Control1 register options
#byte DMA_DMACON2 = 0x0F86 //see DMACON2. Contains control bits for controlling interrupt generation and inter-byte delay behavior. The INTLVL<3:0> bits are used to select when an SSP2IF interrupt should be generated.The function of the DLYCYC<3:0> bits depends on the SPI operating mode (Master/Slave), as well as the DLYINTEN setting.
#word DMA_TXADDR = 0x0F6A //**use DMA_TXADDR(x) for load data(byte reversed). SPI DMA Tranmsit Data Pointer(word)
#word DMA_RXADDR = 0x0F68 //**use DMA_RXADDR(x) for load data(byte reversed). SPI DMA Receive Data Pointer(word)
#word DMA_DMABC = 0x0F66 //**use DMA_DMABC(x) for load data(byte reversed). SPI DMA Data Size(word). (set value 0 to 1023 = 1 to 1024 bytes)
// DMACON1 bits
#bit DMA_SSCON1_ = DMA_DMACON1.7
#bit DMA_SSCON0_ = DMA_DMACON1.6
#bit DMA_TXINC_ = DMA_DMACON1.5
#bit DMA_RXINC_ = DMA_DMACON1.4
#bit DMA_DUPLEX1_ = DMA_DMACON1.3
#bit DMA_DUPLEX0_ = DMA_DMACON1.2
#bit DMA_DLYINTEN_ = DMA_DMACON1.1
#bit DMA_DMAEN_ = DMA_DMACON1.0
//setup_DMA() defines
#define DMA_SSCON_4 0xC0 //Used to control the SS(slave select pin). SS_DMA is asserted each 4 bytes transmitted; DLYINTEN is always reset low
#define DMA_SSCON_2 0x80 //Used to control the SS(slave select pin). SS_DMA is asserted each 2 bytes transmitted; DLYINTEN is always reset low
#define DMA_SSCON_1 0x40 //Used to control the SS(slave select pin). SS_DMA is asserted each 1 byte transmitted; DLYINTEN is always reset low
#define DMA_TXINC 0x20 //Allows the transmit address to increment as the transfer progresses. The transmit address is to be incremented from the initial value of TXADDR<11:0>
#define DMA_RXINC 0x10 //Allows the receive address to increment as the transfer progresses. The received address is to be incremented from the initial value of RXADDR<11:0>
#define DMA_FULL_DUPLEX 0x08 //SPI DMA operates in Full-Duplex mode, data is simultaneously transmitted and received
#define DMA_TX 0x04 //DMA operates in Half-Duplex mode, data is transmitted only
#define DMA_RX 0x00 //DMA operates in Half-Duplex mode, data is transmitted only
#define DMA_DLYINTEN 0x02 //Delay Interrupt Enable bit. Enables the interrupt to be invoked after the number of SCK cycles specified in DLYCYC<2:0> has elapsed from the latest completed transfer. If interrupt is enabled, SSCON<1:0> must be set to ‘00’
#define DMA_DMAEN 0x01
//setup_DMA_int() defines
#define DMA_DLYCYC_2048 0xF0
#define DMA_DLYCYC_1024 0xE0
#define DMA_DLYCYC_896 0xD0
#define DMA_DLYCYC_768 0xC0
#define DMA_DLYCYC_640 0xB0
#define DMA_DLYCYC_512 0xA0
#define DMA_DLYCYC_384 0x90
#define DMA_DLYCYC_256 0x80
#define DMA_DLYCYC_128 0x70
#define DMA_DLYCYC_64 0x60
#define DMA_DLYCYC_32 0x50
#define DMA_DLYCYC_16 0x40
#define DMA_DLYCYC_8 0x30
#define DMA_DLYCYC_4 0x20
#define DMA_DLYCYC_2 0x10
#define DMA_DLYCYC_1 0x00
#define DMA_INTLVL_576 0x0F
#define DMA_INTLVL_512 0x0E
#define DMA_INTLVL_448 0x0D
#define DMA_INTLVL_384 0x0C
#define DMA_INTLVL_320 0x0B
#define DMA_INTLVL_256 0x0A
#define DMA_INTLVL_192 0x09
#define DMA_INTLVL_128 0x08
#define DMA_INTLVL_67 0x07
#define DMA_INTLVL_32 0x06
#define DMA_INTLVL_16 0x05
#define DMA_INTLVL_8 0x04
#define DMA_INTLVL_4 0x03
#define DMA_INTLVL_2 0x02
#define DMA_INTLVL_1 0x01
#define DMA_INTLVL_0 0x00
/*
In SPI Master mode, the DLYCYC<3:0> bits can be usedto control how much time the module will Idle between
bytes in a transfer. By default, the hardware requires a minimum delay of: 8 TCY for FOSC/4, 9 TCY for FOSC/16
and 15 TCY for FOSC/64. Additional delays can be added with the DLYCYC bits. In SPI Slave modes, the
DLYCYC<3:0> bits may optionally be used to trigger an additional time-out based interrupt.
DMA_DLYCYCLES(bits 3 to 0):
1111 = Delay time in number of instruction cycles is 2,048 cycles
1110 = Delay time in number of instruction cycles is 1,024 cycles
1101 = Delay time in number of instruction cycles is 896 cycles
1100 = Delay time in number of instruction cycles is 768 cycles
1011 = Delay time in number of instruction cycles is 640 cycles
1010 = Delay time in number of instruction cycles is 512 cycles
1001 = Delay time in number of instruction cycles is 384 cycles
1000 = Delay time in number of instruction cycles is 256 cycles
0111 = Delay time in number of instruction cycles is 128 cycles
0110 = Delay time in number of instruction cycles is 64 cycles
0101 = Delay time in number of instruction cycles is 32 cycles
0100 = Delay time in number of instruction cycles is 16 cycles
0011 = Delay time in number of instruction cycles is 8 cycles
0010 = Delay time in number of instruction cycles is 4 cycles
0001 = Delay time in number of instruction cycles is 2 cycles
0000 = Delay time in number of instruction cycles is 1 cycle
INTLVL<3:0>: Watermark Interrupt Enable bits
These bits specify the amount of remaining data yet to be transferred (transmitted and/or received)
upon which an interrupt is generated.
1111 = Amount of remaining data to be transferred is 576 bytes
1110 = Amount of remaining data to be transferred is 512 bytes
1101 = Amount of remaining data to be transferred is 448 bytes
1100 = Amount of remaining data to be transferred is 384 bytes
1011 = Amount of remaining data to be transferred is 320 bytes
1010 = Amount of remaining data to be transferred is 256 bytes
1001 = Amount of remaining data to be transferred is 192 bytes
1000 = Amount of remaining data to be transferred is 128 bytes
0111 = Amount of remaining data to be transferred is 67 bytes
0110 = Amount of remaining data to be transferred is 32 bytes
0101 = Amount of remaining data to be transferred is 16 bytes
0100 = Amount of remaining data to be transferred is 8 bytes
0011 = Amount of remaining data to be transferred is 4 bytes
0010 = Amount of remaining data to be transferred is 2 bytes
0001 = Amount of remaining data to be transferred is 1 byte
0000 = Transfer complete
For example, if DMACON2<3:0> = 0101(16 bytes remaining), the SSP2IF interrupt flag will
become set once DMABC reaches 00Fh. If user firmware then clears the SSP2IF interrupt flag, the flag
will not be set again by the hardware until after all bytes have been fully transmitted and the DMA
transaction is complete.
*/