diff options
author | Nebuleon Fumika | 2013-02-03 04:19:11 -0500 |
---|---|---|
committer | Nebuleon Fumika | 2013-02-03 04:19:11 -0500 |
commit | 8693ae1bd880a758eb2efec4fccd32f89593855d (patch) | |
tree | 660b7ceed1789fc904332b96a2a4006b0e4cc6b8 /sdk-modifications/libsrc/dma | |
parent | 02f8184fe07d99cceb85f4abd3ef0e5e3765b5ea (diff) | |
download | snes9x2005-8693ae1bd880a758eb2efec4fccd32f89593855d.tar.gz snes9x2005-8693ae1bd880a758eb2efec4fccd32f89593855d.tar.bz2 snes9x2005-8693ae1bd880a758eb2efec4fccd32f89593855d.zip |
Add SDK modifications by BassAceGold as of 2011-04-14, as well as modified DMA functions as of 2013-01-29.
Diffstat (limited to 'sdk-modifications/libsrc/dma')
-rw-r--r-- | sdk-modifications/libsrc/dma/dma.h | 46 | ||||
-rw-r--r-- | sdk-modifications/libsrc/dma/dma.mk | 9 | ||||
-rw-r--r-- | sdk-modifications/libsrc/dma/dmacopy.c | 167 |
3 files changed, 222 insertions, 0 deletions
diff --git a/sdk-modifications/libsrc/dma/dma.h b/sdk-modifications/libsrc/dma/dma.h new file mode 100644 index 0000000..f6ff230 --- /dev/null +++ b/sdk-modifications/libsrc/dma/dma.h @@ -0,0 +1,46 @@ +#ifndef __DMA_H__ +#define __DMA_H__ + +//register a DMA transfer request +//ch: channel id request, there are 6 channles, +//irq_handler: the DMA interruption handle +//arg: argument to the handle +//mode: DMA mode, such as port width, address increased/fixed, and so on +//type: DMA request type +extern int dma_request(int ch, void (*irq_handler)(unsigned int), unsigned int arg, + unsigned int mode, unsigned int type); + +//start DMA transfer, must request a DMA first +//ch: channel id +//srcAddr: DMA source address +//dstAddr: DMA destination address +//count: DMA transfer count, the total bytes due the mode in dma_request +extern void dma_start(int ch, unsigned int srcAddr, unsigned int dstAddr, + unsigned int count); + +//Stop DMA transfer +extern void dma_stop(int ch); + +//Wait DMA transfer over +extern int dma_wait_finish(int ch); + + +/* + * Copy 'size' bytes from src to dest, in blocks of 32 bytes. + * size is in bytes and must be a multiple of 32. + * Both src and dest must be aligned to 32 bytes. + * Returns 0 on failure, non-zero on success. + */ +extern int dma_copy32Byte(int ch, void *dest, void *src, unsigned int size); +// Blocks of 16 bytes, aligned to 16 bytes +extern int dma_copy16Byte(int ch, void *dest, void *src, unsigned int size); +// Blocks of 4 bytes, aligned to 4 bytes +extern int dma_copy32Bit(int ch, void *dest, void *src, unsigned int size); +// Blocks of 2 bytes, aligned to 2 bytes +extern int dma_copy16Bit(int ch, void *dest, void *src, unsigned int size); +extern int dma_isBusy(int ch); +extern int dma_isFree(int ch); +extern int dma_getFree(void); + +#endif //__DMA_H__ + diff --git a/sdk-modifications/libsrc/dma/dma.mk b/sdk-modifications/libsrc/dma/dma.mk new file mode 100644 index 0000000..0edf343 --- /dev/null +++ b/sdk-modifications/libsrc/dma/dma.mk @@ -0,0 +1,9 @@ +#dma.mk + +SRC += $(DMA_DIR)/dmacopy.c + +SSRC += + +INC += -I$(DMA_DIR) + +CFLAGS +=
\ No newline at end of file diff --git a/sdk-modifications/libsrc/dma/dmacopy.c b/sdk-modifications/libsrc/dma/dmacopy.c new file mode 100644 index 0000000..2c5a2b1 --- /dev/null +++ b/sdk-modifications/libsrc/dma/dmacopy.c @@ -0,0 +1,167 @@ +#include <stdlib.h> +#include "dma.h" +#include "ds2_types.h" + +#define MAX_DMA_NUM 6 /* max 6 channels */ + + +// DMA request source register +#define DMAC_DRSR_RS_BIT 0 +#define DMAC_DRSR_RS_MASK (0x2f << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_UART0OUT (20 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_UART0IN (21 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SSIOUT (22 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SSIIN (23 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AICOUT (24 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AICIN (25 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_MSCOUT (26 << DMAC_DRSR_RS_BIT) //SD0 + #define DMAC_DRSR_RS_MSCIN (27 << DMAC_DRSR_RS_BIT) + + +// DMA channel command register +#define DMAC_DCMD_SAI (1 << 23) /* source address increment */ +#define DMAC_DCMD_DAI (1 << 22) /* dest address increment */ +#define DMAC_DCMD_SWDH_BIT 14 /* source port width */ +#define DMAC_DCMD_SWDH_MASK (0x03 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_32 (0 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_8 (1 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_16 (2 << DMAC_DCMD_SWDH_BIT) +#define DMAC_DCMD_DWDH_BIT 12 /* dest port width */ +#define DMAC_DCMD_DWDH_MASK (0x03 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_32 (0 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_8 (1 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_16 (2 << DMAC_DCMD_DWDH_BIT) +#define DMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */ +#define DMAC_DCMD_DS_MASK (0x07 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_32BIT (0 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_8BIT (1 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_16BIT (2 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_16BYTE (3 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_32BYTE (4 << DMAC_DCMD_DS_BIT) +#define DMAC_DCMD_TM (1 << 7) /* transfer mode: 0-single 1-block */ +#define DMAC_DCCSR_TT (1 << 3) /* transfer terminated */ + +#define DMAC_BASE 0xB3020000 +#define REG32(addr) *((volatile u32 *)(addr)) +#define DMAC_DCCSR(n) (DMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */ +#define REG_DMAC_DCCSR(n) REG32(DMAC_DCCSR((n))) + +#define __dmac_channel_transmit_end_detected(n) \ + ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_TT ) + +/* + * Copy 'size' bytes from src to dest, in blocks of 32 bytes. + * size is in bytes and must be a multiple of 32. + * Both src and dest must be aligned to 32 bytes. + * Returns 0 on failure, non-zero on success. + */ +int dma_copy32Byte(int ch, void *dest, void *src, unsigned int size){ + int test = 0; + if(!(test = dma_request(ch, NULL, 0, + //increment dest addr, increment source addr + DMAC_DCMD_DAI | DMAC_DCMD_SAI | + //set src width 32 bytes, set dest width 32 bytes + DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | + //set copy mode to 32 bytes, copy in blocks + DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TM, + //auto request type + DMAC_DRSR_RS_AUTO))) + { + dma_start(ch, (unsigned int)src, (unsigned int)dest, size); + } + return test; +} + +/* + +int sampleUsage(in ch, void *dest, void *src, unsigned int size){ + //channel 0 is used for mmc stuff, so its best to avoid using it + + //initialize and start copy + if(dma_copy32Byte(ch, dest, src, size)){ + dma_wait_finish(ch);//wait for copy to finish + dma_stop(ch);//must stop after transfer is done to reset channel + return 0; + } + return -1; +} + +*/ + +/* + * Copy 'size' bytes from src to dest, in blocks of 16 bytes. + * size is in bytes and must be a multiple of 16. + * Both src and dest must be aligned to 16 bytes. + * Returns 0 on failure, non-zero on success. + */ +int dma_copy16Byte(int ch, void *dest, void *src, unsigned int size){ + int test = 0; + if(!(test = dma_request(ch, NULL, 0, + DMAC_DCMD_DAI | DMAC_DCMD_SAI | DMAC_DCMD_SWDH_16 | + DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_TM, + DMAC_DRSR_RS_AUTO))) + { + dma_start(ch, (unsigned int)src, (unsigned int)dest, size); + } + + return test; +} + +/* + * Copy 'size' bytes from src to dest, in blocks of 32 bits (4 bytes). + * size is in bytes and must be a multiple of 4. + * Both src and dest must be aligned to 32 bits (4 bytes). + * Returns 0 on failure, non-zero on success. + */ +int dma_copy32Bit(int ch, void *dest, void *src, unsigned int size){ + int test = 0; + if(!(test = dma_request(ch, NULL, 0, + DMAC_DCMD_DAI | DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | + DMAC_DCMD_DS_32BIT | DMAC_DCMD_TM, + DMAC_DRSR_RS_AUTO))) + { + dma_start(ch, (unsigned int)src, (unsigned int)dest, size); + } + + return test; +} + +/* + * Copy 'size' bytes from src to dest, in blocks of 16 bits (2 bytes). + * size is in bytes and must be a multiple of 2. + * Both src and dest must be aligned to 16 bits (2 bytes). + * Returns 0 on failure, non-zero on success. + */ +int dma_copy16Bit(int ch, void *dest, void *src, unsigned int size){ + int test = 0; + + if(!(test = dma_request(ch, NULL, 0, + DMAC_DCMD_DAI | DMAC_DCMD_SAI | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | + DMAC_DCMD_DS_16BIT, + DMAC_DRSR_RS_AUTO))) + { + dma_start(ch, (unsigned int)src, (unsigned int)dest, size); + } + + return test; +} + + +//returns if a channel is still copying +int dma_isBusy(int ch){ + if(ch < 1 || ch >= MAX_DMA_NUM) + return 0; + + return !__dmac_channel_transmit_end_detected(ch); +} + +//returns the first non busy channel +int dma_getFree(void){ + int i; + for(i = 1; i < MAX_DMA_NUM; i++){ + if(!dma_isBusy(i)) + return i; + } + return -1; +} |