RK3288啟動后有三種模式,可以分別進行操作。
第一種是normal也就是正常的啟動模式。這個模式無法刷固件。一般板子通電就是這個模式
第二種是loader模式。就是刷固件模式。這個模式可以刷各種image。按住recover按鍵再通電,通過uboot的檢測進入這個模式
第三種是MASKROM模式。這種模式用于拯救磚頭機器。比如bootloader無法啟動。無法進入loader正常下載。需要通過在板子上找對應的T13 C155 焊點,短接后通電,進入MASKROM模式,這些點需要問板子的生產商。 也可參考鏈接:http://www.t-firefly.com/doc/product/info/287.html
對于模式的檢測是在uboot里面進行的。如果uboot執行有問題。沒法進入loader模式,就需要進入maskrom模式。檢測的代碼在uboot的board_late_init->board_fbt_preboot->board_fbt_key_pressed->checkKey() 根據按鍵的結果確定接下來執行哪一步。checkKey通過配置數據使用GetPortState函數得到是否有按鍵。
配置的內容如下
RockusbKeyInit中
key->type = KEY_AD;
key->key.adc.index = KEY_ADC_CN;
key->key.adc.keyValueLow = 0;
key->key.adc.keyValueHigh= 30;
key->key.adc.data = SARADC_BASE;
key->key.adc.stas = SARADC_BASE+4;
key->key.adc.ctrl = SARADC_BASE+8;
#define SARADC_BASE ? ? ? ? ? ? RKIO_SARADC_PHYS
在io-rk3288.h中
#define RKIO_SARADC_PHYS ? ? ? ? ? ? ? ?0xFF100000
#define RKIO_SARADC_SIZE ? ? ? ? ? ? ? ?SZ_64K
接下來就是到芯片手冊中看資料了
http://rockchip.fr/RK3288%20TRM/
http://wiki.t-firefly.com/index.php/Firefly-RK3288/RK3288_TRM
三通道的模擬信號轉數字信號
Rockchip RK3288TRM V1.0 Technical Reference Manual.pdf
?
可以看到地址FF100000是SAR-ADC的基地址
內存地址從0-FF100000 16M-4GB大小
key->key.adc.index = 1; key->key.adc.keyValueLow = 0; key->key.adc.keyValueHigh= 30; key->key.adc.data = SARADC_BASE; key->key.adc.stas = SARADC_BASE+4; key->key.adc.ctrl = SARADC_BASE+8;
typedef struct
{ uint32 index; uint32 keyValueLow; uint32 keyValueHigh; uint32 data; uint32 stas; uint32 ctrl;
}adc_conf;
對照SAR-ADC源碼進行解析:
for(tt = 0; tt < 10; tt++)
{ // read special gpio port value.
uint32 value; uint32 timeout = 0; /* 控制寄存器清零 初始化狀態 */ write_XDATA32( adc->ctrl, 0); DRVDelayUs(1); /* 寫入 0x0028| 1=0x29 第0 3 5 bit為1 0:2為001 表示選擇輸入源 Input source 1 (SARADC_AIN[1]) 第3bit為1 表示ADC電源啟動 第5bit為1 表示開啟中斷 */ write_XDATA32( adc->ctrl, 0x0028|(adc->index)); DRVDelayUs(1); do { /* 接下來讀取控制寄存器如果第6bit為0那么持續讀取,直到第6bit為1 6bit是中斷狀態位,當轉換結束以后會被設置為1,設置為0表示清除中斷 */ value = read_XDATA32(adc->ctrl); timeout++; } while((value&0x40) == 0); /* 前面的操作就是設置好輸入源開啟中斷這些并開始轉換。 然后等待轉換結束 使用read_XDATA32(adc->data)讀取數據 adc->data得到的是最后一次AD轉換的值 */ value = read_XDATA32(adc->data); //printf("adc key = %d\n",value); //DRVDelayUs(1000); /* 如果最后一次AD轉化的值處于keyValueLow和keyValueHigh之間。 表明電源被接通。計數器+1 keyValueLow和keyValueHigh控制著不同的按鍵類型? */ if( value<=adc->keyValueHigh && value>=adc->keyValueLow) hCnt++;
}
/*
清空初始化狀態
如果10次里面有8次接通,那么說明電源按鈕被按下。返回1
*/
write_XDATA32( adc->ctrl, 0);
return (hCnt>8)
總之根據keyValueHigh和keyValueLow檢測完不同的按鍵后就根據這些按鍵做對應的操作。比如進入loader模式還是normal模式
如果進入的是rockusb那么執行 do_rockusb(NULL, 1, 0, NULL)
參考復制自:https://blog.csdn.net/groundhappy/article/details/56280576