mtk interface
MTK--接口默认分类
MTK--去掉触摸屏校验
1)去掉开机触摸屏校验
先找到SimDetection.c文件中的CallBackPowerOnAnimationComplete函数中的#ifndef
#ifndef __MTK_TARGET__
if (PhnsetNeedFactoryDefaultCalibration()&& !AUTO_POWER)
#else
if (PhnsetNeedFactoryDefaultCalibration())
#endif
将判断条件改为
#ifndef __MTK_TARGET__
if (0)
#else
if (0)
#endif
即可实现
--------------------------------------------------
MTK--mp3 调声音大小
如果想增大音量直接调用:
mmi_audply_press_inc_volume这个接口。
如果想减小音量直接调用:
mmi_audply_press_inc_volume这个接口
------------------------------------------------
MTK--电池告警
当电量低于一定的电压时便会产生电池告警:
在LowBatteryCommonAction这个函数中,会弹出一个BatteryIndicationPopup(STR_LOW_BATTERY);
低电量的屏
------------------------------------------------
MTK---系统重启
调用RstStartRestore函数
------------------------------------------------
MTK--重启手机
调用ex_reboot,或者断言可以重启机器
------------------------------------------------
MTK--audioplay
音频播放器主要有:播放,下一首,上一首,暂停,停止几个按钮。
它们的接口如下:
mmi_audply_press_play_button_down();
mmi_audply_press_play_button_up();
mmi_audply_press_next_button_down();
mmi_audply_press_next_button_up();
mmi_audply_press_prev_button_down();
mmi_audply_press_prev_button_up();
mmi_audply_press_play_button_down();
mmi_audply_press_play_button_up();
mmi_audply_press_stop_button_down();
mmi_audply_press_stop_button_up();
播放和暂停是同一个按钮,当第一次按的时候是播放,再次按下就是暂停,主要控制g_audply.state的
状态。
-----------------------------------------------
MTK----获取系统当前时间
定义一个保存当前时间的结构体:
typedef struct{
U8hour;
U8min;
U8sec;
U8month;
U8day;
U8local;
U16year;
}Btl_Log_Time;
MYTIME init_time;
调用获取当前时间的函数:
GetDateTime(&init_time);
curr_time.year = init_time.nYear;
curr_time.month = init_time.nMonth;
curr_time.day = init_time.nDay;
curr_time.hour = init_time.nHour;
curr_time.min = init_time.nMin;
curr_time.sec = init_time.nSec;
------------------------------------------------
MTK--添加中文字库
添加简体中文字库说明
1. 替换中文字库
将L_1_DiallingFont.h,L_1_Pluto_Large.h,L_1_Pluto_Medium.h,L_1_Pluto_Small.h,L_1_SubLCDFont.h
L_Pluto_ch_GB2312.h,L_virtual_keyboard_font.h替换到//vendor/font/MTK/project/plutommi/content/inc/MainLcd176X220
目录下;
将FontRes.c替换到//vendor/font/MTK/project/plutommi/content/src/MainLcd176X220目录下;
将FontRes.c替换到//plutommi/Customer/CustResource目录下。
2. 打开编译开关
(注:这段代码在MMI_featuresPLUTO.h这个文件的744行左右)
在MMI_featuresPLUTO.h文件中找到如下代码:
#ifdefDEMO_PROJECT
#if !defined(ARIMA27_BB)
//#define__MMI_LANG_TR_CHINESE__
#endif
//#define__MMI_LANG_SM_CHINESE__
#endif
在这段代码之前填加一条语句:
#define __MMI_LANG_SM_CHINESE__
如下面代码所示:
#define __MMI_LANG_SM_CHINESE__
#ifdefDEMO_PROJECT
#if !defined(ARIMA27_BB)
//#define__MMI_LANG_TR_CHINESE__
#endif
//#define__MMI_LANG_SM_CHINESE__
#endif
这样便可打开编译简体中文字库的编译开关。
重新编译即可。
--------------------------------------------
MTK----短信计数的接口
短信计数的接口:
InitSMSCounter(void);
InitNvramSMSCounters()
{
S16 error;
ReadValue(NVRAM_SMSCOUNTERS_SENT_SHORT,&chis_p->nSendSMSCount, DS_SHORT,&error);
if(chis_p->nSendSMSCount == 0xffff)
{
chis_p->nSendSMSCount = 0;
}
ReadValue(NVRAM_SMSCOUNTERS_RECD_SHORT,&chis_p->nRecvSMSCount, DS_SHORT,&error);
if(chis_p->nRecvSMSCount == 0xffff)
{
chis_p->nRecvSMSCount = 0;
}
return;
}
------------------------------------------------
MTK--非易失性内存数据服务
配置指南
要配置数据项,添加或删除一个数据项,或者仅修改某个缺省值,参看以下五个步骤:
1〉 在nvram_user_defs.h 文件里,定义一个新的逻辑数据项的LID至 nvram_LID_cust_enum 枚举。
2〉 在 nvram_user_defs.h 文件里,定义两个常量:SIZE 和 TOTAL。
Linear-fixed: total > 1; size为每一条记录的大小
Transparent: total = 1; size 为每一个数据项实体的大小
注意:由于Flash设备驱动的约束,size定义必须为偶数对齐。
3〉 在 nvram_user_config.c 文件里,定义该新逻辑数据项的缺省值。
注意缺省值的size 必须等于第二步中定义的size大小。
4〉 定义该新逻辑数据项的属性至 logical_data_item_table_cust
定义新数据项和其属性,logical_data_item_table_cust数据结构由NVRAM数据服务内部管理。必须定义的数据结构域:
1〉 LID
2〉 Size
3〉 Total
4〉 Default value:
如果该值为NULL,缺省值为所有字节置0xFF.
如果该值为NVRAM_EF_ZERO_DEFAULT, 缺省值为所有字节置0x00.
5〉 Attributes:
可以为单个数据项赋予多个属性,使用 | 操作。
6〉 Other fields NVRAM 数据服务保留;不要修改它们。
5〉 在 nvram_user_config.c 文件里修改版本号 CODED_DATA_VERSION
每次数据项配置修改,必须修改版本号。数据版本不限于指定的字符,但是长度必须为7 bytes.
2 约束
1.数据项的Size 定义必须为偶数对齐,最大为 65535。
2.Linear fixed 数据项的最大记录数为 65535.
以上的最大值为理论值,可能会因为超出Flash空间而不能正常工作,依赖于Flash设备驱动配置。此外,一部分空间是为协议栈使用,用户可配置的数据项是受限制的。
当前,测试的安全值如下:
1. Size 最大 480
2. Total 最大300
3. 用户可配置的数据项最大值 25
3.2 Fields in Primitives 原语中的域
1.当发送 read/write 请求原语至 NVRAM 任务,如果数据项为 transparent, ’para’ 域必须为1;
2. 当发送 write 请求原语至NVRAM任务, 被写入的数据的大小 size必须等于在nvram_user_config.c中定义的数据项的大小 size.
3. read/write 确认原语成功返回值 ‘result’ 域为:NVRAM_ERRNO_OK,NVRAM_ERRNO_INIT.
----------------------------------------------------------------
MTK----获取IMSI
获取IMSI的代码实现部分:
仅供参考:
void btl_send_msg_get_imsi(void)
{
MYQUEUEMessage;
SetProtocolEventHandler(btl_sim_imsi_rsp, PRT_GET_IMSI_RSP);
Message.oslSrcId = MOD_MMI;
Message.oslDestId = MOD_L4C;
Message.oslMsgId = PRT_GET_IMSI_REQ;
Message.oslDataPtr = NULL;
Message.oslPeerBuffPtr = NULL;
OslMsgSendExtQueue(&Message);
kal_prompt_trace(MOD_MMI,"btl_send_msg_get_imsi");
}
void btl_sim_imsi_rsp(void *info)
{
mmi_smu_get_imsi_rsp_struct *local_data =(mmi_smu_get_imsi_rsp_struct*) info;
kal_prompt_trace(MOD_MMI,"btl_sim_imsi_rsp1");
memcpy(imsi_imei_num, (char *)local_data->imsi,17);
kal_prompt_trace(MOD_MMI,"btl_sim_imsi_rsp2");
}
--------------------------------------------------------
-------------------------------------------------------
MTK----改变CAMERA CAPTURE 的路径
实现代码:
staticvoid mmi_camera_get_next_filename(PS8 file_buf_p)
{
#ifdef __BTL_MOD__
MYTIMEtime;
charfilename[128];
GetDateTime(&time);
if(g_btl_log_ctx.camera_snap.warn_num == 0)
{
kal_wsprintf((WCHAR *)file_buf_p ,"D://Photos//Usual_pic//IMG%d%02d%02d%02d%02d%02d.jpg",
time.nYear , time.nMonth,time.nDay , time.nHour , time.nMin ,time.nSec);
pfnUnicodeStrcpy((S8*)g_btl_log_ctx.get_usual_name.name ,(S8*)file_buf_p);
}
else
{
kal_wsprintf((WCHAR *)file_buf_p ,"D://Photos//Warn_pic//IMG%d%02d%02d%02d%02d%02d.jpg",
time.nYear, time.nMonth, time.nDay, time.nHour, time.nMin,time.nSec);
pfnUnicodeStrcpy((S8*)g_btl_log_ctx.get_warning_name.name ,(S8*)file_buf_p);
}
pfnUnicodeStrcpy((S8*)g_btl_log_ctx.get_usual_name.name ,(S8*)file_buf_p);
dt_ucs2_to_ascii((WCHAR *)file_buf_p , (WCHAR *)filename);
kal_prompt_trace(MOD_MMI ,"get_next_filename: %s" ,filename);
#else
S8buffer[25];
S8UCS2_buffer[50];
S8UCS2_testname[50];
S8UCS2_alpha[10];
S16 error =0;
U16filename_seq_no;
U16alpha_count;
U16alpha_index;
FS_HANDLEfile_handle;
U16file_check = 0;
ReadValue(NVRAM_CAM_FILENAME_SEQ_NO,&filename_seq_no, DS_SHORT,&error);
if(filename_seq_no == 0xffff)
{
filename_seq_no = 1;
}
else
{
filename_seq_no++;
if (filename_seq_no > 9999)
{
filename_seq_no = 1;
}
}
alpha_count = 'Z' - 'A' + 1;
alpha_index= 0;
sprintf((PS8) buffer, "IMG%04d", filename_seq_no);
AnsiiToUnicodeString((PS8) UCS2_buffer, (PS8) buffer);
while(1)
{
sprintf((PS8) buffer, "%c", 'A' + alpha_index);
AnsiiToUnicodeString((PS8) UCS2_alpha, (PS8) buffer);
UCS2Strcpy(UCS2_testname, UCS2_buffer);
UCS2Strcat(UCS2_testname, UCS2_alpha);
UCS2Strcat(UCS2_testname, (PS8) L".jpg");
UCS2Strcpy((PS8) file_buf_p, (PS8)g_camera_cntx.storage_filepath);
UCS2Strcat((PS8) file_buf_p, (PS8) UCS2_testname);
file_handle = FS_Open((U16*) file_buf_p, FS_READ_ONLY);
if (file_handle >= 0)
{
FS_Close(file_handle);
alpha_index++;
}
else
{
WriteValue(NVRAM_CAM_FILENAME_SEQ_NO,&filename_seq_no, DS_SHORT,&error);
return;
}
if (alpha_index >= alpha_count )
{
alpha_count = 'Z' - 'A' + 1;
alpha_index = 0;
filename_seq_no++;
file_check++;
if (filename_seq_no > 9999)
{
filename_seq_no = 1;
}
sprintf((PS8) buffer, "IMG%04d", filename_seq_no);
AnsiiToUnicodeString((PS8) UCS2_buffer, (PS8) buffer);
if (file_check >= 9999)
return;
}
}
#endif
}
2 MTK平台驱动基本介绍 收藏
----------MTK6225
一:LCD
文件位于custom/drv/LCD
以华立维的一款240X320的屏为例介绍如何添加LCD驱动
gprs.mak
LCD_MODULE = HUALIWEI_SSD1289_LCM
MAIN_LCD_SIZE = 240X320
Option
COM_DEFS_FOR_HUALIWEI_SSD1289_LCM = HUALIWEI_SSD1289_LCM SSD1289 COLOR_LCD TFT_MAINLCD QVGA_MAINLCD
在custom/drv/LCD添加HUALIWEI_SSD1289_LCM文件夹,下面有5个文件。文件名同MTK系统自带的(lcd.c lcd_hw.h lcd_sw.h lcd_sw_inc.h lcd_sw_rnd.h)。
HUALIWEI--------------屏的厂家
SSD1289-----------------屏的驱动芯片
LCM----------------------屏
240X320-----------------屏的分辨率
COLOR_LCD----------彩色
TFT_MAINLCD-------屏的类型,对应的还有CSTN,OLED。目前主要是TFT
QVGA_MAINLCD----屏的分辨率
做了上述修改以后,编译时,lcd驱动就对应HUALIWEI_SSD1289_LCM文件夹里的驱动。文件夹里的5个文件,通常lcd_hw.h, lcd_sw_rnd不需要修改。lcd_sw_inc.h只是定义屏的分辨率。如下:
#ifdef __MMI_MAINLCD_128X128__
#define LCD_WIDTH 128
#define LCD_HEIGHT 128
#elif (defined(__MMI_MAINLCD_128X160__))
#define LCD_WIDTH 128
#define LCD_HEIGHT 160
#elif (defined(__MMI_MAINLCD_176X220__))
#define LCD_WIDTH 176
#define LCD_HEIGHT 220
#elif (defined(__MMI_MAINLCD_240X320__))
#define LCD_WIDTH 240
#define LCD_HEIGHT 320
#endif
#define UI_DEVICE_WIDTH LCD_WIDTH
#define UI_DEVICE_HEIGHT LCD_HEIGHT
修改比较多的是lcd.c和lcd_sw.h。
Lcd_sw.h
#define LCD_CMD_DMA_MODE---------是否使用DMA方式?(DMA简单,速度快,通过MTK的寄存器进行操作,但灵活性差。非DMA方式,直接对地址操作,灵活性好,但速度会有影响。目前,一般都是用DMA方式)
#define LCD_16BIT_MODE-----------------lcd使用16位总线?(由硬件决定)
#define LCD_SSD1289_CTRL_ADDR LCD_PARALLEL0_A0_LOW_ADDR
#define LCD_SSD1289_DATA_ADDR LCD_PARALLEL0_A0_HIGH_ADDR
#define MAIN_LCD_CMD_ADDR LCD_SSD1289_CTRL_ADDR
#define MAIN_LCD_DATA_ADDR LCD_SSD1289_DATA_ADDR
#define MAIN_LCD_OUTPUT_FORMAT LCM_16BIT_16_BPP_RGB565_1
#define LCD_delay_SSD1289() /
{/
volatile kal_uint16 iI; /
for (iI = 0; iI < 0x20; iI++);/
}
#ifdef LCD_CMD_DMA_MODE-------------DMA方式
#define LCD_SEND_DMA_CMD(n) /
{/
while (LCD_IS_RUNNING);/
DISABLE_LCD_TRANSFER_COMPLETE_INT;/
DISABLE_ALL_LCD_LAYER_WINDOW;/
SET_LCD_ROI_CTRL_NUMBER_OF_CMD(n);/
ENABLE_LCD_ROI_CTRL_CMD_FIRST;/
SET_LCD_ROI_WINDOW_SIZE(0, 0);/
START_LCD_TRANSFER;/
while (LCD_IS_RUNNING);/
}
#define LCD_CtrlWrite_SSD1289(_data) /
{/
SET_LCD_CMD_PARAMETER(0, LCD_CMD, _data);/ --------写的是命令
LCD_SEND_DMA_CMD(1);/
}
#define LCD_DataWrite_SSD1289(_data) /
{/
SET_LCD_CMD_PARAMETER(0, LCD_DATA, _data);/ --------写的是数据
LCD_SEND_DMA_CMD(1);/
}
#else ----------非DMA方式
#define LCD_CtrlWrite_SSD1289(_data) /
{/
*(volatile kal_uint32 *) LCD_SSD1289_CTRL_ADDR = _data;/ --------写的是命令
LCD_delay_SSD1289();/
}
#define LCD_DataWrite_SSD1289(_data) /
{/
*(volatile kal_uint32 *) LCD_SSD1289_DATA_ADDR = _data;/------------写的是数据
LCD_delay_SSD1289();/
}
#endif
#define LCD_DataRead_SSD1289 (*(volatile kal_uint16 *)LCD_SSD1289_DATA_ADDR);
------用于读LCD id,兼容lcd用。(这个需要硬件上接读lcd的信号)
Lcd.c
LCD_Funcs LCD_func_SSD1289 = {
LCD_Init_SSD1289,
LCD_PWRON_SSD1289,
LCD_SetContrast_SSD1289,
LCD_ON_SSD1289,
LCD_BlockWrite_SSD1289,
LCD_Size_SSD1289,
LCD_EnterSleep_SSD1289,
LCD_ExitSleep_SSD1289,
LCD_Partial_On_SSD1289,
LCD_Partial_Off_SSD1289,
LCD_Partial_line_SSD1289,
LCD_GetParm_SSD1289,
LCD_SetBias_SSD1289,
LCD_Contrast_SSD1289,
LCD_LineRate_SSD1289,
LCD_Temp_Compensate_SSD1289
#ifdef __LCD_ESD_RECOVERY__
,LCD_ESD_check_SSD1289
#endif
};
void LCD_FunConfig(void)
{
MainLCD = &LCD_func_SSD1289;
}
上层通过这个LCD_func_SSD1289来调用相应的lcd驱动函数的。这个结构体里的很多函数不需要修改。经常需要修改的有以下几个函数:
LCD_Init_SSD1289(), LCD_BlockWrite_SSD1289(), LCD_EnterSleep_SSD1289(),
LCD_ExitSleep_SSD1289()。
这其中,LCD_Init_SSD1289(), LCD_EnterSleep_SSD1289(), LCD_ExitSleep_SSD1289(),屏厂会提供,只需要按照写就可以了。LCD_BlockWrite_SSD1289()需要根据LCD的datasheet写。
见ssd1289+2.2topsun-init.txt
LCD_Init_SSD1289()
{
……………….
LCD_CtrlWrite_SSD1289(0x0000);
LCD_DataWrite_SSD1289(0x0001);
LCD_CtrlWrite_SSD1289(0x0003);
LCD_DataWrite_SSD1289(0xa8a4);
…………………
}
void LCD_BlockWrite_SSD1289(kal_uint16 startx,kal_uint16 starty,kal_uint16 endx,kal_uint16 endy)
{
…………………….
SET_LCD_CMD_PARAMETER(0,LCD_CMD, 0x4E); ---------表示寄存器
SET_LCD_CMD_PARAMETER(1,LCD_DATA, startx); ----------表示寄存器中的值
SET_LCD_CMD_PARAMETER(2,LCD_CMD, 0x4F);
SET_LCD_CMD_PARAMETER(3,LCD_DATA, starty);
SET_LCD_CMD_PARAMETER(4,LCD_CMD, 0x44);
SET_LCD_CMD_PARAMETER(5,LCD_DATA, (((endx & 0x00ff)<<8) | (startx & 0x00ff)));
SET_LCD_CMD_PARAMETER(6,LCD_CMD, 0x45);
SET_LCD_CMD_PARAMETER(7,LCD_DATA, starty);
SET_LCD_CMD_PARAMETER(8,LCD_CMD, 0x46);
SET_LCD_CMD_PARAMETER(9,LCD_DATA, endy);
SET_LCD_CMD_PARAMETER(10,LCD_CMD, 0x22);
ENABLE_LCD_TRANSFER_COMPLETE_INT;
ENABLE_LCD_ROI_CTRL_CMD_FIRST;
SET_LCD_ROI_CTRL_NUMBER_OF_CMD(11);
START_LCD_TRANSFER;
}
具体的寄存器意义,见datasheet SSD1289_1.1.pdf (P51)datasheet。这个是一般的lcd调试,特殊的不做描述。
在硬件没有问题的情况下,lcd没有点亮,可做如下动作:
1) 在LCD_Init_SSD1289()函数下加
{
lcd_drive_ic_id = LCD_DataRead_SSD1289;
}
2) LCD_Init_SSD1289()增大lcd复位时间
{
SET_LCD_CTRL_RESET_PIN;
LCD_Delay100us(1000);
CLEAR_LCD_CTRL_RESET_PIN;
LCD_Delay100us(1000);
SET_LCD_CTRL_RESET_PIN;
LCD_Delay100us(1000);
}
3) LCD_Init_SSD1289()添加测试代码
{
{
unsigned int m,n;
GPIO_ModeSetup(25, 0);
GPIO_InitIO(1, 25);
GPIO_WriteIO(1, 25);
for(m=0; m<240; m++)
for(n=0; n<320; n++)
{
LCD_DataWrite_SSD1289(0xf800);
}
}-----------用于判断初始化代码是否正确
}
4) 修改时序,主要是写的时序void init_lcd_interface(void)
{
SET_LCD_PARALLEL_CE2WR_SETUP_TIME((kal_uint32)3);
SET_LCD_PARALLEL_CE2WR_HOLD_TIME(4);
SET_LCD_PARALLEL_CE2RD_SETUP_TIME(3);
SET_LCD_PARALLEL_WRITE_WAIT_STATE(7);
SET_LCD_PARALLEL_READ_LATENCY_TIME(31);
SET_LCD_ROI_CTRL_CMD_LATENCY(10);
}
5) 初始化正确的前提下,检查函数LCD_BlockWrite_SSD1289()。这个时候,屏上应该有显示了。只是显示不正常。
二:键盘
通常只需要修改keypad_def.c文件。
一般硬件会提供如下
C0 C1 C2 C3 C4
R1 UP 7 Right 9 VOL+
R2 左软件 OK Down 3 VOL-
R3 SEND 0 8 # 播放/暂停
R4 Left 1 2 右软 快退
R5 * 4 5 6 快进
软件只需要填进去就可以了。
const keypad_struct keypad_custom_def = {
{
DEVICE_KEY_SK_LEFT,
DEVICE_KEY_SEND,
DEVICE_KEY_SK_RIGHT,
DEVICE_KEY_UP,
DEVICE_KEY_VOL_UP,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_1,
DEVICE_KEY_4,
DEVICE_KEY_7,
DEVICE_KEY_MENU,
DEVICE_KEY_VOL_DOWN,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_2,
DEVICE_KEY_5,
DEVICE_KEY_8,
DEVICE_KEY_DOWN,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_3,
DEVICE_KEY_6,
DEVICE_KEY_9,
DEVICE_KEY_LEFT,
DEVICE_KEY_FUNCTION,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_STAR,
DEVICE_KEY_0,
DEVICE_KEY_HASH,
DEVICE_KEY_RIGHT,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END
},
Custom_Keypress_Period,
};
三:音频PA开关 afe.c
void AFE_SwitchExtAmplifier( char sw_on )
{
if( sw_on )
{
GPIO_WriteIO( 1, 5 );----------使用的是GPIO5,每个项目会不同,需根据硬件修改
}
else
{
GPIO_WriteIO( 0, 5 );
}
}
四:USB电源开关 usb_custom.c
void USB_PowerControl(kal_bool enable)
{
#ifdef __USB_ENABLE__
GPIO_ModeSetup(35, 0); --------使用的是GPIO35,每个项目会不同,需根据硬件修改
GPIO_InitIO(1, 35);
if (enable == KAL_TRUE)
GPIO_WriteIO(1,35);
else
GPIO_WriteIO(0,35);
#endif
}
五:lcd背光custom_equipment.c
kal_bool custom_cfg_gpio_set_level(kal_uint8 gpio_dev_type, kal_uint8 gpio_dev_level )
{
case GPIO_DEV_LED_MAINLCD:
……………
break;
}
lcd背光驱动,一般有以下两种方式:
1) PWM方式
GPIO_ModeSetup(25, 2);
PWM_level(gpio_dev_level);
2) gpio脉冲方式。这个根据背光芯片的要求,可能有所不同。
{
GPIO_ModeSetup(25, 0);
GPIO_InitIO(1, 25);
if (gpio_dev_level == LED_LIGHT_LEVEL0)
{
GPIO_WriteIO(0, 25);
BL_Delay50us(100);
}
else
{
kal_uint8 level_array[6] = {0, 28, 20, 10, 6, 2};
savedMask=SaveAndSetIRQMask();
for(j=0; j< level_array[gpio_dev_level]; j++)
{
volatile kal_uint16 delay;
GPIO_WriteIO(0,25);
for (delay =0;delay <5;delay++){}
GPIO_WriteIO(1, 25 );
for (delay =0;delay <5;delay++){}
}
RestoreIRQMask(savedMask);
BL_Delay50us(20);
}
}
六:键盘背光custom_equipment.c
kal_bool custom_cfg_gpio_set_level(kal_uint8 gpio_dev_type, kal_uint8 gpio_dev_level )
{
case GPIO_DEV_LED_KEY:
……………
break;
}
一般通过gpio口拉高拉低来开关。不同项目,gpio口可能不同。
{
GPIO_InitIO(1, 27);
GPIO_ModeSetup(27, 0);
if (gpio_dev_level == LED_LIGHT_LEVEL0)
{
GPIO_WriteIO(0,27);
}
else
{
GPIO_WriteIO(1,27);
}
}
七:振动custom_equipment.c
kal_bool custom_cfg_gpio_set_level(kal_uint8 gpio_dev_type, kal_uint8 gpio_dev_level )
{
case GPIO_DEV_VIBRATOR:
……………
break;
}
一般通过gpio口拉高拉低来开关。不同项目,gpio口可能不同。
{
GPIO_InitIO(1, 6);
GPIO_ModeSetup(6, 0);
if (gpio_dev_level == LED_LIGHT_LEVEL0)
{
GPIO_WriteIO(0,6);
}
else
{
GPIO_WriteIO(1,6);
}
break;
}
八:flash修改custom_MemoryDevice.h
首先硬件会提供项目中使用的flash型号或datasheet。然后到mcu/tools
/MemoryDeviceList/ MemoryDeviceList_XXX..xls(一般是日期最靠前的那个)查找,是否有flash对应的型号。如果有,表示软件支持这颗flash,如果没有,表示软件不支持这颗flash,那需要调加或需要MTK释放新的软件。
支持的话,需用将custom_MemoryDevice.h中添加对应的型号
#define CS0_PART_NUMBER S71GL128NB0BFW9Z
#define CS1_PART_NUMBER S71GL128NB0BFW9Z
通常来说,开不了机,首先要检查flash是否配置正确。
九:ADC的配置adc_channel.c
const kal_uint8 ADC_VBAT = 0;
const kal_uint8 ADC_VISENSE = 1;
const kal_uint8 ADC_VBATTMP = 2;
const kal_uint8 ADC_VCHARGER = 3;
const kal_uint8 ADC_ACCESSORYID = 5;
const kal_uint8 ADC_PCBTMP = 4;
#if defined(__CHARGER_USB_DETECT_WIHT_ONE_EINT__)
const kal_uint8 ADC_CHR_USB = 6;
#endif
如果需要修改,硬件工程师会提供ADC对应的功能。
十:外部中断的配置eint_def.c
const kal_uint8 AUX_EINT_NO = 0;
const kal_uint8 CHRDET_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#if defined(__PHONE_CLAMSHELL__) || defined(__PHONE_SLIDE__)
const kal_uint8 CLAMDET_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#endif
#ifdef __USB_ENABLE__
const kal_uint8 USB_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#else
const kal_uint8 USB_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#endif
#ifdef __BT_SUPPORT__
const kal_uint8 BT_EINT_NO = 1;
#endif
#if defined(__CHARGER_USB_DETECT_WIHT_ONE_EINT__)
const kal_uint8 CHR_USB_EINT_NO = 2;
#endif
#ifdef __SWDBG_SUPPORT__
const kal_uint8 SWDBG_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#endif
#if defined(MOTION_SENSOR_SUPPORT)
const kal_uint8 MOTION_SENSOR_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#endif
#if defined(TOUCH_PANEL_SUPPORT) || defined(HAND_WRITING)
const kal_uint8 TOUCH_PANEL_EINT_NO = 3;
#endif
#ifdef __WIFI_SUPPORT__
const kal_uint8 WIFI_EINT_NO = EINT_CHANNEL_NOT_EXIST;
#endif
一般,EINT_CHANNEL_NOT_EXIST表示硬件上没有这个中断,也就是没有这个功能。如果需要修改,硬件工程师会提供相关的资料。
十一:触摸屏
触摸屏相关的文件有eint_def.c,touch_panel.c,touch_panel.h,touch_panel_buffer.h,
touch_panel_custom.c,touch_panel_custom.h,touch_panel_main.c,touch_panel_spi.c,
touch_panel_spi.h,touchscreen.c。
而对驱动来说,一般需要修改以下文件:
eint_def.c
#if defined(TOUCH_PANEL_SUPPORT) || defined(HAND_WRITING)
const kal_uint8 TOUCH_PANEL_EINT_NO = 3;
#endif
kal_uint8 custom_eint_sw_debounce_time_delay[EINT_MAX_CHANNEL] =
{
50,
0,
50,
0
};
touch_panel_spi.h
#define SPI_DIN_PIN 0
#define SPI_CLK_PIN 40
#define SPI_DOUT_PIN 42
#define SPI_CS_PIN 32
#define SPI_BUSY_PIN 30
触摸屏对应的控制引脚,由硬件决定
touch_panel.c
kal_uint32 ADC_X_START=370;
kal_uint32 ADC_X_END=3740;
kal_uint32 ADC_Y_START=300;
kal_uint32 ADC_Y_END=3690;
kal_uint32 SCREEN_X_START=0;
kal_uint32 SCREEN_X_END=240;
kal_uint32 SCREEN_Y_START=0;
kal_uint32 SCREEN_Y_END=320;
touch_panel_custom.h
#define TOUCH_PANEL_ADC_X_START 370
#define TOUCH_PANEL_ADC_X_END 3740
#define TOUCH_PANEL_ADC_Y_START 300
#define TOUCH_PANEL_ADC_Y_END 3690
#define TOUCH_PANEL_COORD_X_START 0
#define TOUCH_PANEL_COORD_X_END 239
#define TOUCH_PANEL_COORD_Y_START 0
#define TOUCH_PANEL_COORD_Y_END 319
touch_panel.c和touch_panel_custom.h的值是对应的。这个值不正确,会导致触摸屏不校准,触摸屏不能用。这个值可以简单得到;
touch_panel_custom.c
format下载完以后,点击触摸屏的左上脚(x_start,y_start)
和右下脚(x_end,y_end),得到的值就是,可以通过log得到。
void tp_read_adc(kal_int16 *x, kal_int16 *y)
{
*y=serial_read_data();
*x=serial_read_data();
kal_prompt_trace(MOD_MMI,”!!!!!!! *x = %d *y = %d”,*x,*y);
}
十二:蓝牙,目前都是用BTMTK_MT6601
一般需要修改btmtk_config.c和eint_def.c
eint_def.c
#ifdef __BT_SUPPORT__
const kal_uint8 BT_EINT_NO = 1;
#endif
btmtk_config.c
#ifdef __BTMODULE_MT6601__
const unsigned char bt_gpio_setting[16] =
{ 34, 1, // power on : pin(if use GPO, please plus 100), pol
3, 1, // reset : pin(if use GPO, please plus 100), pol
1, 1, // bt2gsm : pin(EINT n), pol
49, 50, // rxd3, txd3
0xFF, 0xFF, // cts3, rts3
0xff, 0xff, // lpoclk, mode
51, 54, // PCM clk, PCM sync
52, 53 // PCM data output, PCM data input
};
#endif
蓝牙对应的控制引脚,由硬件决定
十三:FM
目前使用的FM有MT6188,SI4700,RDA5800。
MT6188的驱动对应的文件是MT6188.c。通常来说,只需要修改
#define CRYCLK 26 //GPIO26
//这个脚不一定需要,根据硬件 #define LE 4 /// GPIO4
#define SDA 48 //GPIO48
#define SCL 47 //GPIO47
SI4700和RDA5800对应的驱动文件是SI4700。
一般需要的修改的也是控制引脚
#define RST 1
#define EN 4
#define SCLK 47
#define SDIO 48
#define FM_CLK 26
添加SI4700的驱动
gprs.mak
FM_RADIO_CHIP = SI4720 #MT6188
/fm_drv/下添加文件
SI4700_drv.c
/make/fm_drv/fm_drv.lis文件中添加
fm_drv/SI4700_drv.c
十四:camera
gprs.mak
CMOS_SENSOR = OV7670
camera相关的文件位于
/custom/drv/camera/DESHENG25_GEMINI_BB/
/custom/drv/yuv_sensor/
一般需要修改如下文件:
camera_hw.c
#define MODULE_POWER_PIN 34// camera电源脚
Sccb.h
#define SCCB_SERIAL_CLK_PIN 8 //SCL
#define SCCB_SERIAL_DATA_PIN 9 //SDA
/custom/drv/yuv_sensor/OV7670下的image_sensor.c,image_sensor.h
一般来说,image_sensor.c和image_sensor.h由camera厂商提供。
如果要新添加一种camera,如MC501CB。
则:
gprs.mak
CMOS_SENSOR = MC501CB
/custom/drv/yuv_sensor/
下添加文件夹MC501CB。文件夹下有如下文件:image_sensor.c, image_sensor.h,usbvideo_attr.c。
image_sensor.c和image_sensor.h由camera厂商提供,而usbvideo_attr.c一般不需要修改。
十五:射频修改
一般修改如下几个文件:l1d_custom_rf.h,m12193.c,m12193.h,chr_parameter.c
射频会提供相应的参数,只需要找到相应的位置,填进去。
十六:音频参数的修改nvram_default_audio.c
这个文件对应正常,耳机,免提模式下的音频参数。
GAIN_NOR_XXX 正常模式
GAIN_HED_XXX 耳机模式
GAIN_HED_XXX 免提模式
十七:初始gpio配置gpio_drv.c
void GPIO_init(void)
{
}
这个函数对gpio口进行初始的配置。如果配置不正确,会引起耗流问题。根据
硬件来写。
自己动手做驱动的总结:
一、 键盘的驱动
键盘的驱动一般都是在文件keypad_def.c文件中修改
硬件会提供如下键盘的定义表:
列(读)
行(写) KCOL0 KCOL1 KCOL2 KCOL3 KCOL4
KROW0 多功键 0 返回 上
KROW1 左 8 右 OK
KROW2 拨号 * 6 下
KROW3 1 7 3 2
KROW4 4 # 9 5
KROW5
GND PWRKEY
驱动按照上面的表,按行列对照修改下面的一个结构体就行了
const keypad_struct keypad_custom_def = {
{
// #ifndef __CUST_NEW__
DEVICE_KEY_SK_LEFT,
DEVICE_KEY_0,
DEVICE_KEY_SK_RIGHT,
DEVICE_KEY_UP,//DEVICE_KEY_3,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_LEFT,
DEVICE_KEY_8,
DEVICE_KEY_RIGHT,
DEVICE_KEY_MENU,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_SEND,
DEVICE_KEY_STAR,
DEVICE_KEY_6,//DEVICE_KEY_MP3,
DEVICE_KEY_DOWN,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_1,
DEVICE_KEY_7,
DEVICE_KEY_3,
DEVICE_KEY_2,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_4,
DEVICE_KEY_HASH,
DEVICE_KEY_9,
DEVICE_KEY_5,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_NONE,
DEVICE_KEY_END,
//#else
// KEYPAD_MAPPING
// #endif
},
Custom_Keypress_Period,
#ifndef __CUST_NEW__
DEVICE_KEY_END //在此处定义开机键,一般定义成END键
#else
POWERKEY_POSITION
#endif
};