/* dwdma linked list struct */
struct llp_t {
uint32_t sar;
uint32_t dar;
struct llp_t *llp;
uint32_t ctl_l;
uint32_t ctl_h;
uint32_t dstat;
};

uint16_t dst_buff[240][400];
uint16_t src_buff[240][400];

/* structs which describe full screen update */
struct llp_t scr_llp[LCD_HEIGHT];


static void llp_setup(void *src, void *dst, struct llp_t *llp, uint32_t size)
{
llp->sar = (uint32_t)src;
llp->dar = (uint32_t)dst;
llp->llp = llp + 1;
llp->ctl_h = size;
llp->ctl_l = (1<<20) |
(1<<23) |
(1<<17) |
(2<<1) |
(2<<4) |
(3<<11) |
(3<<14) |
(1<<27) |
(1<<28);
}

static void llp_end(struct llp_t *llp)
{
llp->ctl_l &= ~((1<<27)|(1<<28));
}


static void dwdma_start(uint8_t ch, struct llp_t *llp, uint8_t handshake)
{
DWDMA_SAR(ch) = 0;
DWDMA_DAR(ch) = 0;
DWDMA_LLP(ch) = (uint32_t)llp;
DWDMA_CTL_L(ch) = (1<<20) |
(1<<23) |
(1<<17) |
(2<<1) |
(2<<4) |
(3<<11) |
(3<<14) |
(1<<27) |
(1<<28);

DWDMA_CTL_H(ch) = 1;
DWDMA_CFG_L(ch) = (7<<5);
DWDMA_CFG_H(ch) = (handshake<<11)|(1<<2);
DWDMA_SGR(ch) = (13<<20);
DWDMA_DMA_CHEN = (0x101<<ch);

}

static void dwdma_init(void)
{
DWDMA_DMA_CHEN = 0xf00;
DWDMA_CLEAR_BLOCK = 0x0f;
DWDMA_DMA_CFG = 1; /* global enable */
}

bool dbg_ports(void)
{
int i,j = 0;
int fd;

/* build src array */
for (i=0; i<240; i++)
for(j=0; j<400; j++)
src_buff[i][j] = ((i*400 + j) & 0xffff);

/* build LLPs */
for (i=0; i<240; i++)
llp_setup(&src_buff[i], &dst_buff[i], &scr_llp[i], LCD_WIDTH/2);
llp_end(&scr_llp[LCD_HEIGHT-1]);

dwdma_init();

LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU;
MCU_CTRL = ALPHA_BASE(0x3f) | MCU_CTRL_BYPASS;
HOR_BP = LCD_WIDTH + 3;
VERT_BP = LCD_HEIGHT;

LINE0_YADDR = 0;
LINE1_YADDR = (1 * LCD_WIDTH/2);
LINE2_YADDR = (2 * LCD_WIDTH/2);
LINE3_YADDR = (3 * LCD_WIDTH/2);

LINE0_UVADDR = 1;
LINE1_UVADDR = (1 * LCD_WIDTH/2) + 1;
LINE2_UVADDR = (2 * LCD_WIDTH/2) + 1;
LINE3_UVADDR = (3 * LCD_WIDTH/2) + 1;

lcdctrl_bypass(0);

//memset((void *)&LCD_BUFF, 0x00, 2048*4);

dwdma_start(0, scr_llp, 6);

MCU_CTRL=(1<<1)|(1<<2)|(1<<5);
while (!(LCDC_STA & LCDC_MCU_IDLE));

fd = open("/src_buff.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd > 0)
{
_backlight_off();
sleep(HZ);
_backlight_on();
}
write(fd, src_buff, sizeof(src_buff));
close(fd);

fd = open("/dst_buff.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd > 0)
{
_backlight_off();
sleep(HZ);
_backlight_on();
}
write(fd, dst_buff, sizeof(dst_buff));
close(fd);

_backlight_off();
sleep(2*HZ);
_backlight_on();
while(1);
}