T I w i f i 模块驱动笔记

本文介绍了TI WL18xx无线模块的驱动编译流程及注意事项,包括环境搭建、内核配置调整、驱动源码修改等步骤,并提供了连网测试的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wl18xx wiki: http://processors.wiki.ti.com/index.php/WL18xx?DCMP=wilink8&HQS=wilink8wiki

编译过程参考: http://processors.wiki.ti.com/index.php/WL18xx_System_Build_Scripts

使用TI的驱动编译脚本编译,R8.4, R8.3 SP1,使用R8.3 SP1.

1. 下载:

user@ubuntu:~$ mkdir utility

user@ubuntu:~$ cd utility

user@ubuntu:~/utility$ git clonegit://github.com/TI-ECS/build-utilites.git

Cloning into 'build-utilites'...

remote: Counting objects: 223, done.

remote: Compressing objects: 100% (176/176), done.

remote: Total 223 (delta 115), reused 145 (delta 40)

Receiving objects: 100% (223/223), 78.98 KiB | 61 KiB/s,done.

Resolving deltas: 100% (115/115), done.

user@ubuntu:~/utility$ ls

build-utilites

user@ubuntu:~/utility$ cd build-utilites/

user@ubuntu:~/utility/build-utilites$ ls

functions scripts             wl12xx_build.sh

patches   setup-env.sample   wl18xx_build_bt.sh  wl18xx_build_ble.sh  wl18xx_build.sh

README    wl12xx_build_bt.sh wlan_enable_config.sh

user@ubuntu:~/utility/build-utilites$

 

由于使用的kernel版本为3.2,需要设置:

git reset --hard ol_r8.a8.10_32

 

2. 在setup-env设置环境变量,主要有内核路径,gcc路径,和驱动源码目录

 

export CROSS_COMPILE="arm-none-linux-gnueabi-"

export PATH="$PATH:/usr/local/arm-2010q1/bin"      gcc路径

export ROOTFS=/home/tom/wl18xx_build_utilites/rootfs  rootfs目录,执行install,将驱动copy到这个目录下,编译也需要这个目录下的头文件

exportWORK_SPACE=/home/tom/wl18xx_build_utilites/workspace 源码目录,包括wl18xx驱动,还有其他的源码,我们只关心wl18xx的源码

exportKLIB_BUILD=/home/tom/myd-am335x/kernel/linux-3.2.0-psp04.06.00.08.sdk2linux内核目录

export BUILD_VERSION="r8"

# MACHINE_TYPE - The target machine type. Can have one ofthe following values: "am1808" , "omap3evm" ,"am335x"

# This is needed to build bluetooth components.

# This parameter is not relevant for ti814x board.

export MACHINE_TYPE="am335x"                           am335x cpu

 

3. 硬件说明

WLAN_IRQ一定要用,不用会出现错误:

wlcore: ERROR ELP wakeup timeout!

注意WL_EN引脚在VBAT和VIO上电的时候需要是低电平,在内核初始化过程中需要把该引脚拉高,还必须延时100ms左右,否则内核

启动会检测到不wl18xx模块.

 

4. 修改内核配置和驱动源码

    http://processors.wiki.ti.com/index.php/WL18xx_WiFi_Build_Process这里有对内核配置的说明

    TI修改了cfg80211和mac80211源码,所以需要配置:

CONFIG_BT=N

CONFIG_CFG80211=N

CONFIG_MAC80211=N 

驱动编译的时候也会检查内核配置,如果不符合要求,会有提示.

 

驱动的WLAN_IRQ使用的是上升沿中断,我们的板加了一个MOS管反相了,中断线平时是高电平,所以需要修改源码,

设置中断类型为下降沿中断:

compat-wireless\drivers\net\wireless\ti\wlcore\main.c

static void wlcore_nvs_cb(const struct firmware *fw, void*context)

{

...

   if (wl->platform_quirks &WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {

      //irqflags = IRQF_TRIGGER_RISING;

      irqflags = IRQF_TRIGGER_FALLING;

      printk("WLAN IRQ: Fallinginterrupt\n");

      hardirq_fn = wlcore_hardirq;

   } else {

      irqflags = IRQF_TRIGGER_HIGH |IRQF_ONESHOT;

   }

...

需要全编译一次后,才能修改驱动源码,因为全编译之后才会下载源码

 

5. 编译

    第一次先执行一次全编译:

    ./wl18xx_build.shall

    单独编译wl18xx驱动

    ./wl18xx_build.shwl18xx_modules build    //编译

    ./wl18xx_build.shwl18xx_modules install  //将驱动安装到rootfs目录下

    源码目录:

   

    compat-wireless是wl18xx驱动,./wl18xx_build.shwl18xx_modules build会先将该目录删除,再解压新的源码,

    所以如果需要修改源码,需要修改编译脚本(wl18xx_build.sh):

 

6. 驱动加载

    执行./wl18xx_build.shwl18xx_modules install之后,会将驱动模块安装到rootfs/lib/modules/3.2.0目录下:

   

    驱动在updates目录下,用到的驱动文件有compat.komac80211.ko cfg80211.ko wlcore.ko wlcore_sdio.ko wl18xx.ko,

    驱动的依赖关系modules.dep文件中有说明,加载顺序:

    insmodcompat.ko

    insmodcfg80211.ko

    insmodmac80211.ko

    insmodwlcore.ko

    insmodwl18xx.ko

    insmodwlcore_sdio.ko

 

6. 连网

   

    得使用rootfs/usr/sbin目录下的wpa_supplicant去连

    wpa_supplicant-i wlan0 -c /etc/wpa_supplicant.conf -Dnl80211 -B,

    注意不能使用参数-Dwext

 

 

 

<think>我们正在讨论Synopsys DesignWare I2C模块中的SDA接收保持时间(I2C_SDA_RX_HOLD)的测量问题。根据提供的引用信息,特别是引用[3]中提到了设备树配置,引用[4]提到了驱动名称(i2c-designware),我们可以推断出目标硬件平台使用的是DesignWare I2C IP核。 测量I2C_SDA_RX_HOLD时间通常需要示波器或逻辑分析仪来捕获SDA和SCL信号。但是,由于I2C_SDA_RX_HOLD是一个特定的寄存器参数,它定义了在接收模式下,SDA数据线在SCL时钟下降沿之后需要保持的时间(以时钟周期为单位)。因此,测量这个时间实际上需要验证硬件行为是否符合寄存器设置。 步骤: 1. 确认寄存器设置:首先需要知道当前I2C_SDA_RX_HOLD寄存器的值。在DesignWare I2C中,这个寄存器通常称为IC_SDA_HOLD(具体名称可能因版本而异)。我们需要在驱动中查找或直接读取该寄存器的值。 2. 设置测试环境:为了测量接收保持时间,我们需要让I2C作为接收方(从设备或主设备接收数据)。可以设计一个测试场景,例如让另一个I2C主设备向被测的DesignWare I2C模块发送数据,同时用示波器捕获SDA和SCL信号。 3. 测量方法:在示波器上,观察SCL的下降沿,然后测量从SCL下降沿到SDA数据线发生变化(即释放)的时间。这个时间就是接收保持时间,它应该等于寄存器设置的值乘以I2C模块的时钟周期。 但是,根据引用[2](Synopsys DW_apb_i2c_databook笔记),DesignWare I2C模块的配置寄存器中确实有IC_SDA_HOLD寄存器,它分为两部分:TX_HOLD和RX_HOLD。我们关注的是RX_HOLD。 具体操作: 步骤1:确定寄存器地址和值 在Linux系统中,如果驱动已经加载,我们可以通过访问寄存器映射来读取IC_SDA_HOLD寄存器的值。但是,这通常需要内核模块的支持。另外,我们也可以查看设备树中是否配置了该值。在引用[3]的设备树节点中,并没有直接看到sda-hold-time的配置,但我们可以尝试在设备树中添加该属性(如果支持的话)。例如: i2c0: i2c@28002000 { compatible = "snps,designware-i2c"; ... sda-hold-time-ns = <300>; /* 例如,300纳秒 */ }; 然后重新加载设备树,并检查驱动是否读取了这个值并写入寄存器。 步骤2:通过调试接口读取寄存器 如果系统支持,我们可以通过/sys/kernel/debug/下的调试接口或者直接使用devmem2工具(或其他内存访问工具)读取寄存器物理地址的值。首先需要知道IC_SDA_HOLD寄存器的偏移地址。根据DesignWare I2C的文档,该寄存器的偏移量是0x74(请以实际文档为准,不同版本可能不同)。然后,我们需要知道I2C模块的基地址(在设备树中定义,例如0x28002000),那么寄存器的物理地址就是0x28002000 + 0x74。 使用devmem2读取: devmem2 0x28002074 注意:需要root权限,并且确保该地址可访问。 步骤3:示波器测量 连接示波器探头到SDA和SCL线上。设置触发条件为SCL的下降沿,并确保在数据传输阶段(特别是接收数据时)捕获波形。在接收数据时,SDA线由发送方控制,但在接收方(DesignWare I2C)需要读取数据时,它不会驱动SDA(因为接收方不驱动SDA),所以SDA的变化是由发送方控制的。然而,保持时间实际上是接收方内部的一个要求,它规定了在SCL下降沿之后,数据必须保持稳定的时间。因此,这个时间是由发送方保证的。但是,接收方内部会有采样窗口,这个寄存器设置会影响接收方在SCL下降沿之后多久才允许改变数据(实际上,这个寄存器是为了满足接收方的内部时序要求,确保数据稳定)。 因此,严格来说,接收保持时间并不是由接收方主动保持的,而是发送方需要满足的时序要求。但是,DesignWare I2C模块的IC_SDA_HOLD寄存器(RX部分)实际上是为了调整内部采样点的延迟,以适应不同的传输延迟。所以,我们测量的是从SCL下降沿到SDA数据线被发送方改变的时间,这个时间应该大于等于接收方要求的保持时间(即寄存器设置的时间)。 所以,我们测量的是发送方在SCL下降沿后保持SDA稳定的时间,然后与寄存器设置的值进行比较。 步骤4:计算 寄存器IC_SDA_HOLD中RX_HOLD的值是一个以i2c_clk(模块时钟)周期为单位的数值。例如,如果模块时钟是100MHz(周期10ns),寄存器值为30,则要求的保持时间为300ns。在示波器上测量到的实际保持时间应大于等于300ns。 注意事项: - 由于I2C是开漏结构,SDA的变化可能不是瞬间的,所以测量时要注意信号的斜率。 - 如果使用上拉电阻,上升时间可能会较长,可能会影响保持时间的测量。 如果无法直接读取寄存器,或者需要验证寄存器设置是否正确,可以在驱动代码中查找设置该寄存器的部分。在Linux内核中,DesignWare I2C驱动的代码通常是drivers/i2c/busses/i2c-designware-*.c。在驱动中,通常会根据设备树中的sda-hold-time-ns属性来计算寄存器值。 例如,在函数i2c_dw_set_sda_hold()中,会计算寄存器值: reg = dw_readl(dev, DW_IC_SDA_HOLD); /* 设置RX_HOLD部分 */ ... dw_writel(dev, reg, DW_IC_SDA_HOLD); 总结: 要测量SDA接收保持时间,需要: 1. 确定寄存器IC_SDA_HOLD中RX_HOLD的值(通过寄存器读取或驱动代码确认)。 2. 使用示波器在I2C接收数据时,测量SCL下降沿到SDA数据线改变的时间(至少测量多个样本取平均)。 3. 将测量时间与寄存器设置的时间(寄存器值乘以模块时钟周期)进行比较。 相关问题: 1. 如何修改Synopsys DesignWare I2C模块的接收保持时间? 2. 在I2C时序中,接收保持时间与发送保持时间有何区别? 3. 为什么需要设置SDA的保持时间? 4. 如何通过设备树配置DesignWare I2C的SDA保持时间?</think>要测量 Synopsys DesignWare I2C 模块中的 SDA 接收保持时间(`I2C_SDA_RX_HOLD`),需结合硬件测量和寄存器配置验证。以下是具体步骤: --- ### **测量步骤** 1. **确认寄存器配置** - `I2C_SDA_RX_HOLD` 的值存储在 DesignWare I2C 的 **IC_SDA_HOLD** 寄存器中(偏移量通常为 `0x74`)[^2][^3]。 - 通过调试工具读取寄存器值(需 root 权限): ```bash # 假设 I2C 控制器基地址为 0x28002000 devmem2 0x28002074 # 读取 IC_SDA_HOLD 寄存器 ``` - 寄存器结构示例: $$ \text{IC\_SDA\_HOLD} = [\text{TX\_HOLD} \quad | \quad \text{RX\_HOLD}] $$ 其中 **RX_HOLD** 即接收保持时间(单位为 I2C 模块时钟周期)。 2. **计算理论时间值** - 若寄存器中 `RX_HOLD = N`,且 I2C 模块时钟频率为 $f_{\text{clk}}$(例如 100 MHz),则理论保持时间为: $$ t_{\text{hold}} = \frac{N}{f_{\text{clk}}} $$ 例如 $N=30$, $f_{\text{clk}}=100\ \text{MHz}$ 时,$t_{\text{hold}} = 300\ \text{ns}$。 3. **示波器测量硬件信号** - **触发条件**: - 通道 1:SCL 下降沿(标记采样点)。 - 通道 2:SDA 信号变化点(从稳定到跳变的时刻)。 - **测量方法**(如图): ![I2C SDA Hold Time](https://www.analog.com/-/media/analog/en/landing-pages/technical-articles/i2c-primer-part-1-hardware/figure3.png?la=en&w=435#0.5x) - 测量 SCL 下降沿到 SDA 信号跳变的时间差 $\Delta t$(即实际保持时间)。 - **要求**:$\Delta t \geq t_{\text{hold}}$(理论值)。 4. **验证与调试** - 若实测 $\Delta t$ 过小,需增大 `RX_HOLD` 寄存器值: ```c // 驱动代码示例(Linux 内核) void update_rx_hold(struct i2c_adapter *adap) { struct dw_i2c_dev *dev = i2c_get_adapdata(adap); u32 reg = dw_readl(dev, DW_IC_SDA_HOLD); reg &= ~0xFFFF; // 清零 RX_HOLD 位域 reg |= (new_rx_hold & 0xFFFF); // 设置新值 dw_writel(dev, reg, DW_IC_SDA_HOLD); } ``` - 修改后重复步骤 1-3 验证时序是否满足。 --- ### **注意事项** 1. **时钟同步** DesignWare I2C 模块以最高速率采样总线[^2],需确保测量时 I2C 时钟频率与配置一致(设备树中 `clock-frequency = <100000>` 表示 100 kHz 标准模式)[^3]。 2. **信号完整性** - 使用高阻抗探头,减少测量干扰。 - 检查 PCB 上拉电阻(通常 1–10 kΩ)是否匹配信号上升时间。 3. **驱动兼容性** 若使用 `i2c-designware` 驱动[^4],确认驱动版本是否支持 `IC_SDA_HOLD` 寄存器操作(部分旧版本需手动添加配置)。 --- ### **相关问题** 1. 如何通过设备树配置 DesignWare I2C 的 SDA 保持时间? 2. I2C 时序中,接收保持时间与发送保持时间有何区别? 3. 为什么 I2C 需要时钟拉伸(Clock Stretching)?它与保持时间有何关联? 4. 如何诊断因保持时间不足导致的 I2C 通信错误? [^1]: I2C 总线时序规范参考(UM10204)。 [^2]: DesignWare I2C 起始字节传输协议说明。 [^3]: 设备树配置与 DesignWare I2C 驱动实现细节。 [^4]: Linux 内核中 DesignWare I2C 驱动的兼容性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值