/* * DMA C definitions and help macros * */ #ifndef dma_h #define dma_h /* registers */ /* Really needed, since both are listed in sw.list? */ #include "dma_defs.h" /* descriptors */ // ------------------------------------------------------------ dma_descr_group typedef struct dma_descr_group { struct dma_descr_group *next; unsigned eol : 1; unsigned tol : 1; unsigned bol : 1; unsigned : 1; unsigned intr : 1; unsigned : 2; unsigned en : 1; unsigned : 7; unsigned dis : 1; unsigned md : 16; struct dma_descr_group *up; union { struct dma_descr_context *context; struct dma_descr_group *group; } down; } dma_descr_group; // ---------------------------------------------------------- dma_descr_context typedef struct dma_descr_context { struct dma_descr_context *next; unsigned eol : 1; unsigned : 3; unsigned intr : 1; unsigned : 1; unsigned store_mode : 1; unsigned en : 1; unsigned : 7; unsigned dis : 1; unsigned md0 : 16; unsigned md1; unsigned md2; unsigned md3; unsigned md4; struct dma_descr_data *saved_data; char *saved_data_buf; } dma_descr_context; // ------------------------------------------------------------- dma_descr_data typedef struct dma_descr_data { struct dma_descr_data *next; char *buf; unsigned eol : 1; unsigned : 2; unsigned out_eop : 1; unsigned intr : 1; unsigned wait : 1; unsigned : 2; unsigned : 3; unsigned in_eop : 1; unsigned : 4; unsigned md : 16; char *after; } dma_descr_data; // --------------------------------------------------------------------- macros // enable DMA channel #define DMA_ENABLE( inst ) \ do { reg_dma_rw_cfg e = REG_RD( dma, inst, rw_cfg );\ e.en = regk_dma_yes; \ REG_WR( dma, inst, rw_cfg, e); } while( 0 ) // reset DMA channel #define DMA_RESET( inst ) \ do { reg_dma_rw_cfg r = REG_RD( dma, inst, rw_cfg );\ r.en = regk_dma_no; \ REG_WR( dma, inst, rw_cfg, r); } while( 0 ) // stop DMA channel #define DMA_STOP( inst ) \ do { reg_dma_rw_cfg s = REG_RD( dma, inst, rw_cfg );\ s.stop = regk_dma_yes; \ REG_WR( dma, inst, rw_cfg, s); } while( 0 ) // continue DMA channel operation #define DMA_CONTINUE( inst ) \ do { reg_dma_rw_cfg c = REG_RD( dma, inst, rw_cfg );\ c.stop = regk_dma_no; \ REG_WR( dma, inst, rw_cfg, c); } while( 0 ) // give stream command #define DMA_WR_CMD( inst, cmd_par ) \ do { reg_dma_rw_stream_cmd __x = {0}; \ do { __x = REG_RD(dma, inst, rw_stream_cmd); } while (__x.busy); \ __x.cmd = (cmd_par); \ REG_WR(dma, inst, rw_stream_cmd, __x); \ } while (0) // load: g,c,d:burst #define DMA_START_GROUP( inst, group_descr ) \ do { REG_WR_INT( dma, inst, rw_group, (int) group_descr ); \ DMA_WR_CMD( inst, regk_dma_load_g ); \ DMA_WR_CMD( inst, regk_dma_load_c ); \ DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \ } while( 0 ) // load: c,d:burst #define DMA_START_CONTEXT( inst, ctx_descr ) \ do { REG_WR_INT( dma, inst, rw_group_down, (int) ctx_descr ); \ DMA_WR_CMD( inst, regk_dma_load_c ); \ DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \ } while( 0 ) // if the DMA is at the end of the data list, the last data descr is reloaded #define DMA_CONTINUE_DATA( inst ) \ do { reg_dma_rw_cmd c = {0}; \ c.cont_data = regk_dma_yes;\ REG_WR( dma, inst, rw_cmd, c ); } while( 0 ) #endif