RK3288啓動後有三種模式,能夠分別進行操做。php
第一種是normal也就是正常的啓動模式。這個模式沒法刷固件。通常板子通電就是這個模式html
第二種是loader模式。就是刷固件模式。這個模式能夠刷各類image。按住recover按鍵再通電,經過uboot的檢測進入這個模式app
第三種是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函數獲得是否有按鍵。ui
配置的內容以下spa
RockusbKeyInit中.net
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;3d
#define SARADC_BASE RKIO_SARADC_PHYScode
在io-rk3288.h中orm
#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