📄 dmac.c
字号:
/*
Motorola LTE Display Memory Access Controller Driver
----------------------------
(c) motoprogger 2008
*/
#include "../libs/motolibs.h"
#define DMAC_BASE 0x24854000
#define DMAC_DATA_BASE_ADDRESS_H hword_ptr(DMAC_BASE+0x000)
#define DMAC_DATA_BASE_ADDRESS_L hword_ptr(DMAC_BASE+0x002)
#define DMAC_DATA_BUFFER_SIZE_H hword_ptr(DMAC_BASE+0x004)
#define DMAC_DATA_BUFFER_SIZE_L hword_ptr(DMAC_BASE+0x006)
#define DMAC_COMMAND_BASE_ADDRESS_H hword_ptr(DMAC_BASE+0x008)
#define DMAC_COMMAND_BASE_ADDRESS_L hword_ptr(DMAC_BASE+0x00A)
#define DMAC_COMMAND_BUFFER_SIZE_H hword_ptr(DMAC_BASE+0x00C)
#define DMAC_COMMAND_BUFFER_SIZE_L hword_ptr(DMAC_BASE+0x00E)
#define DMAC_COMMAND_STRING_SIZE hword_ptr(DMAC_BASE+0x010)
#define DMAC_FIFO_CONFIG hword_ptr(DMAC_BASE+0x012)
#define DMAC_LCD_CONFIG hword_ptr(DMAC_BASE+0x014)
#define DMAC_LCD_TRANSFER_CONFIG hword_ptr(DMAC_BASE+0x016)
#define DMAC_CONTROL_STATUS hword_ptr(DMAC_BASE+0x018)
#define DMAC_LCD_CLOCK_CONFIG hword_ptr(DMAC_BASE+0x01A)
#define DMAC_LCD_WRITE_DATA hword_ptr(DMAC_BASE+0x01C)
static byte dmac_data_pol=1;
void dmac_config(hword transfer_config, hword clock_config, hword data_pol)
{
hword buf;
DMAC_DATA_BASE_ADDRESS_H=0;
DMAC_DATA_BASE_ADDRESS_L=0;
DMAC_DATA_BUFFER_SIZE_H=0;
DMAC_DATA_BUFFER_SIZE_L=0;
DMAC_COMMAND_BASE_ADDRESS_H=0;
DMAC_COMMAND_BASE_ADDRESS_L=0;
DMAC_COMMAND_BUFFER_SIZE_H=0;
DMAC_COMMAND_BUFFER_SIZE_L=0;
DMAC_COMMAND_STRING_SIZE=0;
DMAC_LCD_TRANSFER_CONFIG=transfer_config;
buf=DMAC_CONTROL_STATUS;
buf&=~0x73;
buf|=0x100;
DMAC_CONTROL_STATUS=buf;
buf=DMAC_CONTROL_STATUS;
buf&=~0x73;
buf|=0x80;
DMAC_CONTROL_STATUS=buf;
dmac_data_pol=data_pol&1;
buf=DMAC_CONTROL_STATUS;
buf&=~0x1800;
buf|=dmac_data_pol<<11;
DMAC_CONTROL_STATUS=buf;
DMAC_LCD_CLOCK_CONFIG=clock_config;
}
bool dmac_check_busy(void)
{
return (DMAC_CONTROL_STATUS&4)!=0;
}
void dmac_wait(void)
{
while(dmac_check_busy());
}
void dmac_abort(void)
{
DMAC_CONTROL_STATUS|=2;
dmac_wait();
}
void dmac_send_byte(byte abyte, bool isdata)
{
hword wr_data;
wr_data=abyte|(dmac_data_pol==isdata)<<8;
dmac_wait();
DMAC_LCD_WRITE_DATA=wr_data;
}
void dmac_send_data_direct(void * data, word length)
{
dmac_wait();
DMAC_DATA_BASE_ADDRESS_H=((word) data)>>16;
DMAC_DATA_BASE_ADDRESS_L=(hword) (word) data;
DMAC_DATA_BUFFER_SIZE_H=(hword)(length>>16);
DMAC_DATA_BUFFER_SIZE_L=(hword)length;
DMAC_CONTROL_STATUS|=1;
}
void dmac_send_data(void * data, word length)
{
word down_128k;
word end1, end2;
word lim_len;
byte * byte_data;
word data_addr;
byte_data=(byte * ) data;
while (((word) byte_data)&3 && length)
{
dmac_send_byte(*byte_data,true);
byte_data++;
length--;
}
do
{
data_addr=(word) (void * ) byte_data;
down_128k=data_addr&~0x1FFFF;
end1=(data_addr+length)&~0x3;
end2=down_128k+0x20000;
if (end1<end2) lim_len=end1-data_addr;
else lim_len=end2-data_addr;
if (lim_len!=0)
{
dmac_send_data_direct(byte_data, lim_len);
byte_data+=lim_len;
length-=lim_len;
}
}
while (lim_len!=0);
while (length)
{
dmac_send_byte(*byte_data,true);
byte_data++;
length--;
}
}
void dmac_send_cmd_one(byte cmd, byte data)
{
dmac_send_byte(cmd,false);
dmac_send_byte(data,true);
}
void dmac_send_cmd_two(byte cmd, byte data1, byte data2)
{
dmac_send_cmd_one(cmd,data1);
dmac_send_byte(data2, true);
}
void dmac_send_cmd_three(byte cmd, byte data1, byte data2, byte data3)
{
dmac_send_cmd_two(cmd,data1,data2);
dmac_send_byte(data3, true);
}
void dmac_send_cmd_long(byte cmd, byte * data, word length)
{
dmac_send_byte(cmd,false);
dmac_send_data(data,length);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -