RK3288的几种USB模式

RK3288启动后有三种模式,能够分别进行操做。php

一种是normal也就是正常的启动模式。这个模式没法刷固件。函数

通常板子通电就是这个模式ui


第二种是loader模式。就是刷固件模式。这个模式能够刷各类image。spa

按住recover按键再通电,经过uboot的检测进入这个模式code


第三种是MASKROM模式。这种模式用于拯救砖头机器。好比bootloader没法启动。没法进入loader正常下载。orm

须要经过在板子上找对应的T13 C155 焊点,短接后通电,进入MASKROM模式,这些点须要问板子的生产商。blog


对于模式的检测是在uboot里面进行的。若是uboot执行有问题。无法进入loader模式,就须要进入maskrom模式。ip

检测的代码在uboot的board_late_init->board_fbt_preboot->board_fbt_key_pressed->checkKey() 根据按键的结果肯定接下来执行哪一步。内存


checkKey经过配置数据使用GetPortState函数获得是否有按键。ci

配置的内容以下

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)