hooku

Please enjoy some eccentric technologies.

proj_pjsip

OTIS pjsip

Git Repo: https://github.com/hooku/pjproject Branch: hooku_pjsip2.10

功能

  1. 实现pjlib在NUC980上的编译,对不需要的功能进行裁剪
  2. pjlib适配使用Audio Switchboard以及Pass Through的Codec
  3. pjmedia对接桥通的vpdemo底层驱动库,实现DSP音频编解码调用
  4. 编译pjdemo程序pjsua,提供配置文件,完成SIP与Twilio服务器的对接
  5. 调试SIP通话的音质,以及SIP程序的稳定性
  6. 对SIP程序进行优化,降低CPU占用率

桥通开发板配置

系统版本

需要升级至 1.0.8 unpacker Airbridge_q1.0.8_2020-09-23_1548_8c3476c4.bin

使用以太网上网

ifconfig eth0 192.168.68.99 netmask 255.255.255.0
route delete default
route add default gw 192.168.68.1
echo "nameserver 192.168.68.1" > /etc/resolv.conf
killall dhcpd
killall netmonitor.sh

otis_iot_sdk

Git Repo: https://gitee.com/airbridge/otis_iot_sdk

编译

make dir=package/test

pjsip

编译

所需要的环境

  • NUC980BSP/otis_iot_sdk

编译命令

./configure --prefix=/home/pxj/Desktop/otis/pjsip/output2.10 \
--host=arm-linux \
--disable-sdl \
--disable-ffmpeg \
--disable-v412 \
--disable-openh264 \
--disable-resample \
--disable-video \
--disable-speex-aec \
--disable-g711-codec \
--disable-l16-codec \
--disable-gsm-codec \
--disable-g722-codec \
--disable-g7221-codec \
--disable-speex-codec \
--disable-ilbc-codec \
--disable-darwin-ssl \
--disable-ssl \
--disable-opencore-amr \
--disable-silk \
--disable-opus \
--disable-bcg729 \
--disable-libyuv \
--disable-libwebrtc

make distclean

make dep && make clean && make

开启调试

CFLAGS="-g3 -O0" \
CXXFLAGS="-g3 -O0"

运行 pjsua

pjsip 编译完会在 pjsip-apps/bin 生成 pjsua-arm-unknown-linux-gnu,传输至开发板,然后运行

./pjsua-arm-unknown-linux-gnu --config twilio.config

pjsip 配置文件

# This is a comment in the config file.
--id sip:[email protected]
--registrar sip:caizhimin1986.sip.us1.twilio.com
--realm sip.twilio.com
--username +15614199179
--password IWasAtSignal2017
sip:[email protected]

依赖的库

ld-uClibc-1.0.19.so
libasound.so.2.0.0
libuClibc-1.0.19.so
  • 库链接脚本
rm /lib/ld-uClibc.so.0
 rm /lib/ld-uClibc.so.1
 rm /lib/ld-uClibc-1.0.19.so

 ln -s /nvm/lib/ld-uClibc-1.0.19.so /lib/ld-uClibc.so.0
 ln -s /nvm/lib/ld-uClibc-1.0.19.so /lib/ld-uClibc.so.1
 ln -s /nvm/lib/ld-uClibc-1.0.19.so /lib/ld-uClibc-1.0.19.so

 rm /usr/lib/libasound.so
 rm /usr/lib/libasound.so.2
 rm /usr/lib/libasound.so.2.0.0

 ln -s /nvm/lib/libasound.so.2.0.0 /usr/lib/libasound.so
 ln -s /nvm/lib/libasound.so.2.0.0 /usr/lib/libasound.so.2
 ln -s /nvm/lib/libasound.so.2.0.0 /usr/lib/libasound.so.2.0.0

 rm /lib/libuClibc-1.0.19.so
 rm /lib/libc.so.0
 rm /lib/libc.so.1

 ln -s /nvm/lib/libuClibc-1.0.19.so /lib/libuClibc-1.0.19.so
 ln -s /nvm/lib/libuClibc-1.0.19.so /lib/libc.so.0
 ln -s /nvm/lib/libuClibc-1.0.19.so /lib/libc.so.1

 chmod +x /nvm/lib/*

sip 调试信息

Twilio

 sip:[email protected]
 sip:[email protected]
  • Twilio 登录信息

用户名:[email protected][email protected] 密码:H3H*.pWc.@tL,RQ

sip 调试步骤

  1. 打开 Twilio 网页调试器,确保右侧的状态显示如下内容

> Requesting Access Token... > Got a token. > Twilio.Device Ready!

  1. 运行 pjsua

USB笔记

USB

USB结构

USB是一种Tiered Start(分层星型)拓扑结构。
一个USB总线口最多能连接127个设备(包括HUB)(因Address Field是7b)。
USB最多能接6层,每层的线缆最大长度是5M(USB 1.1及以后的Spec移除了线缆长度限制),因此总的USB连线长度最大是6*5=30M。

所有的USB的初始通信都是由Host发出的,因此Device之间是不能直接通信的。
即使Device需要向Host发送数据,也需要等到Host下次轮询的时候才能发送。
唯一的特例是Device在Suspend模式下,能够主动向Host发送一个“远程唤醒”的信号。

USB电源

USB LS的最大线缆长度要比HS、FS的小。

Device、HUB只能从上游接口取电;
Self-powered(自供电) Device不从USB Bus取电。
使用USB Bus电源的设备称为"bus-powered" device,其能获取100mA的电流;在与Host协商完成后,最大可获取500mA的电流。

接口

1 2 3 4 5
Vbus D- D+ ID

USB版本与速度

速度 带宽 版本
USB Low Speed 1.5Mbps 1.0
USB Full Speed 12Mbps 1.0
USB High Speed 480Mbps 2.0+
USB SuperSpeed 5Gbps 3.0+
USB SuperSpeedPlus 10Gbps 3.1+

SuperSpeed 与 SuperSpeedPlus

SuperSpeed总线能够以双向约460MB/s传输数据,SuperSpeedPlus则能够达1.1GB/s。

USB电气特性

USB使用NRZI编码方式,进行差分信号传输。
USB的数据以LSB的方式传输。

传输信号“1”: 发送方将D+下拉(>2.8V),并将D-上拉(<0.3V);
接收方把D+大于D- 200mV当作“1”,把D+小于D- 200mV当作“0”。

USB速度识别

当USB Device未插入时,D+和D-都是0V(因为USB Host端的D+/D-接了15K的下拉电阻接地。

  • Full Speed: D+上拉至3.3V
  • Low Speed: D-上拉至3.3V
  • High Speed: 先作为Full Speed接入,随后协商进入High Speed

USB暂停模式(Suspend Mode)

所有的USB设备都必须支持暂停模式。
如果USB Device的bus连续3毫秒没有数据,将进入暂停模式。
USB每个单元(Unit)允许的最大电流为500uA。例如,某个设备配置为500mA的Max Power,并且启用了“远程唤醒”的功能,那该设备在Suspend模式下可以获取0.5*(500/100)=2.5mA的电流。

USB包

Token(令牌包)

Token包:

Sync PID ADDR ENDP CRC5 EOP
  • Sync: 同步头(Low & Full Speed:8位,High Speed:32位)
  • PID: 包ID,标记包的类型,用以区分是Token、Data还是Handshake,以及其子类型;4位*2,传输两次PID,第二次取反,这样能够检测错误
  • ADDR: 设备地址(1~127),地址0供还未分配ADDR的设备使用
  • ENDP: Endpoint,4位
  • EOP: End of Packet,SE0+J

Token 包的类型:

  1. In: 通知Device Host想要读取信息
  2. Out: 通知Device Host想要发送信息
  3. Setup: 开始传输控制
Data(数据包)

Data包:

Sync PID Data CRC16 EOP

Data包的类型:

  1. Data0
  2. Data1
  3. Data2 (High Speed)
  4. MDATA (High Speed)
速度 Data载荷
Low Speed 8B
Full Speed 1023B
High Speed 1024B
Handshake(握手包)

Handshaka包:

Sync PID EOP

Handshaka包的类型:

  1. ACK: 包成功接收
  2. NAK: 表示Device不能发送或接收数据或者Host没有数据需要发送/remove
  3. STALL: 表示当前Device的状态需要Host干预
SOF (Start of Frame Marker)

Host每隔1ms发送一次SOF,用于作为Device的时间基准,以及防止Device进入Suspend State(作Keep-alive用)。?

USB 1.1 Host控制器接口Spec

分为两种:

  1. UHCI(Universal Host Controller Interface),支持LS、FS,更依赖软件,PC中较为常见。
  2. OHCI(Open Host Controller Interface),支持LS、FS,更依赖硬件,嵌入式设备中较常见。

USB 2.0 Host控制器接口Spec

EHCI(Enhanced Host Controller Interface),只支持HS,LS、FS的传输任务由UHCI或OHCI控制器完成。

USB Endpoint(EP)

USB Endpoint的长度是4b,因此最大EP个数是 2^4,即16个。
Low Speed USB最多只能有4个EP。

所有的Device必须支持对EP0的操作,由于EP0负责了在USB枚举时所有的Device控制、状态请求。

USB的4种传输类型(EP类型)

4种传输类型的比较:

名称 错误检测 时间保证 支持Low Speed 使用场景 说明
Control ? ? 命令传输、状态控制 ?
Bulk 是(CRC16) 大块数据传输 在USB总线空闲时,传输最快
Interrupt ? ? ? ?
Isochronous(同步) ? ? 有最大的带宽
Control传输

Setup Stage:

graph LR
    token(SETUP) --> data(DATA0)
    data --> hanshake(ACK)

Data Stage:

IN Transaction:

graph LR
    token(IN) --> data1(DATA x)
    data1 --> |传输正常完成|handshake(ACK)
    token --> |传输出错|data2(STALL)
    token --> |传输仍在进行|data3(NAK)

OUT Transaction:

graph LR
    token(OUT) --> data(DATA x)
    data --> |传输正常完成|handshake1(ACK)
    data --> |传输出错|handshake2(STALL)
    data --> |传输仍在进行|handshake3(NAK)

Status Stage:

IN Transaction:

graph LR
    token(OUT) --> data(DATA0, 长度=0)
    data --> |传输正常完成|handshake1(ACK)
    data --> |传输出错|handshake2(STALL)
    data --> |传输仍在进行|handshake3(NAK)

OUT Transaction:

graph LR
    token(IN) --> |传输正常完成|data1(DATA0, 长度=0)
    data1 --> handshake1(ACK)
    token(IN) --> |传输出错|handshake2(STALL)
    token(IN) --> |传输仍在进行|handshake3(NAK)
Interrupt传输
Isochronous传输
Bulk传输

USB 枚举

USB Pipe

Pipe(管道)指的是Host与EP之间的逻辑连接关系。

Pipe类型 传输格式 支持的传输类型 控制方
Stream Pipe USB协议没有定义其格式 Bulk, Isochronous, Interupt Host与Device
Message Pipe USB协议定义了其格式 Control 仅Host

USB枚举

Windows7 对USB的枚举

Windows7系统默认的USB协议栈没有包括USB3.0

  1. 等待USB Port稳定

Hub驱动会至少等100ms来确保Port连接稳定。如果超过200ms仍然没有稳定,Hub驱动将不会进行枚举,并且会禁用该。

  1. 发出第一个Port Reset

Port的状态变为Connected & Enabled,USB Device会响应地址为0的请求。

  1. 发出第一个Device Descriptor Request

  2. 发出第二个Port Reset

i.MX6处理器的USB

i.MX6处理器的USB主要分为USB Controller以及USB 2.0 PHY两部分。

USB Controller

i.MX6的USB Controller符合USB 2.0的协议,支持High Speed(HS)、Full Speed(FS)以及Low Speed(LS)。 该Controller包含了两种Core:OTG Core以及Host Core(低端的处理器不包含此Core)。

Controller中包含了3个Core。

Core名称 别名 接口 连接的Port 备注
Core0 OTG1 Core UTMI OTG1 Port 支持充电检测(Charge Detection)
Core1 OTG2 Core UTMI OTG2 Port 不支持充电检测
Core2 Host1 Core HSCI Host1 Port

每个Core都有其独立的中断向量表(除了USB wake-up(唤醒)中断);USB wake-up中断是由32K时钟驱动的Power Control模块触发的。

OTG Core可以工作在Host模式或者Device模式,其只能与UTMI接口的Phy连接,最大支持8个EP。
Host Core只能工作在Host模式,其只能与HSIC接口连接。

Controller支持两种工作模式:Normal Mode, Low Power Mode。
在Device模式下,Controller能够自动进入Suspend State,而在Host模式下,需要通过Software的方式进入Suspend State(包括OTG Core以及Host Core)。
从Suspend State唤醒时,USB的wake-up中断也能够用来激活ARM platform的时钟。

Host状态下Controller可在如下事件被唤醒:

事件 说明
远程唤醒请求 设备在DP/DM上发送wake-up信号
电流过载 Power Control模块检测到总线上的电流大于一定值(Descriptor预设值?)
USB断开 设备断开连接导致DP/DM发生改变
USB连接

USB Controller的寄存器

Controller的寄存器分为以下三类:

寄存器类型 读/写 说明
Identification类寄存器 只读? 用于配置USB硬件参数
Capability类寄存器 只读 表明当前Controller的功能,以及哪些功能受到限制
Operational类寄存器 读/写/写入清除 控制Controller的功能

Host Data Structure(HDS)

HDS定义了HCD(Host Controller Driver)(软件)与EHC(Enhanced Host Controller)之间控制、传输的接口。

USB 2.0 PHY

i.MX6处理器内部有2个USB 2.0的PHY,支持HS,FS及LS;PHY使用标准的UTMI接口(16位,时钟频率30MHz),与USB Controller连接。
内部?PLL提供了120MHz的时钟源,UTMI进行4分频,获得30MHz的频率。

------------------          -------------------------------------------
|                |  <-----  =Digital Receiver       Analog Receiver   = <-----  USB D+/D-
| USB Controller |  ----->  =Digital Transmitter    Analog Transmitter= ----->  USB D-/D+ 
|                |   UTMI   |               USB PHY                   |     USB Cable
------------------          -------------------------------------------

Digital Transmitter/Receiver

在USB HS时,Digital Transmitter从USB Controller接收16b的并行数据,并以30MHz的频率将其串行化为480Mb的HS数据(包括NRZI编码,位填充等);随后将结果输出至对应HS、FS、LS的Analog Transmitter。

Analog Receiver/Transmitter

  • Analog Receiver主要包含了HS差分信号Receiver、静噪Detector、LS/FS差分信号Receiver、HS断开连接Detector、USB插入Detector、单端的USB_DP/USB_DN Receiver、9X过采样模块。
  • Analog Transmitter主要包含了HS45Ω电阻、LS/FS差分驱动器、HS差分驱动器、1.5KΩ DP上拉电阻、15KΩ DP下拉电阻。

USB充电检测单元

  • 数据线连接检测:当USB插头插入时,电源针脚(USB Vbus、GND)会比数据针脚(DP、DM)先连接上(因为他们长一点);充电检测单元提供了对DP、DM是否连接上的检测功能。
  • 充电器类型检测:充电检测单元能够检测出当前的USB连接是否能进行充电。如果需要区分连接的到底是充电器还是电脑USB,可以通过拉高DP,并检测DN电平的方式来判断充电器类型。
  • Deadly Battery Protect:在电池耗尽的设备上插入USB时,充电检测单元能够自动向PMIC报告是否连接到了充电器,使得PMIC能够从USB口获取大于100mA的电流。

参考

USB in a NutShell
USB human interface device class
USB Made Simple
USB Overview
How does USB stack enumerate a device?

NAND学习笔记

NAND

本文的NAND均指RAWNAND。

SLC,MLC,TLC

NAND类型 理论可擦写次数 每单元存储bit数
SLC 100,000 1
MLC 10,000 2
TLC 3000~5000 3

NAND标准

NAND标准主要分为ONFi和JEDC标准。 ONFi标准的NAND通常支持Async,NVDDR,NVDDR2,NVDDR3模式,主要NAND厂商是Micron, Hynix, Intel, SanDisk。
JEDC标准的NAND通常支持Async,Toggle模式,主要NAND厂商是Samsung, Toshiba。

标准 发布时间 Async NV-DDR NV-DDR2 NV-DDR3 Toggle 1.0 Toggle 2.0
ONFI 1.0 2006 50MT/s
ONFI 2.0 2008 50MT/s 133MT/s
ONFI 2.1 2009 50MT/s 200MT/s
ONFI 3.0 2011 50MT/s 200MT/s 400MT/s
JESD230 2012 50MT/s 200MT/s 400MT/s 133MT/s
ONFI 3.2 2013 50MT/s 200MT/s 533MT/s
JESD230B 2014 50MT/s 200MT/s 533MT/s 133MT/s 400MT/s
ONFI 4.0 2014 50MT/s 200MT/s 667MT/s 800MT/s
JESD230C 2016 50MT/s 200MT/s 667MT/s 133MT/s 400MT/s
ONFI 4.1 2017 50MT/s 200MT/s 667MT/s 1200MT/s

NV-DDR模式在ONFi2.3之前又作Sync模式。

Toggle模式

Toggle模式采用了一根双向的DQS信号, 不需要一根单独的时钟信号。
当Host向NAND发送数据时,DQS信号由Host端控制;Host接收数据时,DQS信号由NAND控制。
Sync模式下,时钟信号是连续发送的,而Toggle模式只在读写时传输DQS信号;因此Toggle模式比Sync模式省电。

NAND层次

LU0 LU1 .. LUn
Block 0 Block 0 ..
Page 0
Page 1
...
Page x
Block 1 Block 1 ..
Page 0
...
Page x
Block 2 Block 2 ..
...
Page Reg0 Page Reg1 ..
  • LUN(Logical Unit Number):指闪存能够执行命令、获取状态的最小单元。例如,可以在LUN0进行写入时,对LUN1进行读取。
  • Block是最小的擦除单位。如果每个Block包含的Page个数不是2的幂,地址应与大于他的最近的2的幂对齐。
  • Page是最小的读写单位。(某些闪存支持Partial Page,比如可以设置Column地址,来指定从Page的某个Offset开始,直到整个Page读完)
  • Page Reg用来缓存即将存入Page,或刚从Page取出的数据。

NAND地址分为

  1. Column Address(行地址):表示数据在Page中的偏移量。在Row Address之前发送,但是如Block Erase之类的指令无需发送该地址。
  2. Row Address(列地址):LUN+Block+Page的地址。

坏块标记(Bad Block Marker)

在NAND出厂时,当某个Block有缺陷时,该Block的第一个Page的OOB处(通常会在当前Block的最前面3个Page,以及最后面3个Page)标记坏块信息(BBM)。
没有缺陷的Block此处应为0xFF,有缺陷则标记为0x0。其他不等于0xFF的值也将被认为是坏块。
在初次使用NAND闪存时,厂商通常会提供一个NAND烧写工具,该工具会遍历NAND上所有的BBM,并在NAND上创建一个表,称作BBT(Bad Block Table)。 这个表会把所有的坏块记录下来,方便后续访问NAND(有了BBT,就不需要每次读取一个新的Block之前再访问这个Block的BBM了)。

常用引脚

引脚 I/O 全称 说明
CE# I Chip Enable 当R/B#信号为低电平时(如正进行读写、擦除操作),CE#可以上拉,选择另一个NAND芯片进行操作。
R/B# O Ready/Busy Output 低电平时表示LUN正忙
CLE I Command Latch Enable 指令锁存使能,用于区分当前I/O口传的是命令还是地址。
ALE I Address Latch Enable 地址锁存使能
WE# I Write Enable 写使能
RE# I Read Enable 读使能
IO0-7,8-15 I/O I/O Port NAND总线宽度可以是8位,或者16位的,但是所有的地址传输只用低8位总线(高8位填0)
DQS I Data Strobe
WP# I Write Protect 拉底后,对闪存的写入、擦除命令失效

对NAND检测及初始化

  1. Controller拉底CE#,选中NAND。
  2. Controller向NAND发送Reset命令。
  3. Controller向NAND发送Read ID命令,若NAND回应了正确的ID,则可初步判断Controller与NAND的连接配置正确。

大部分ONFi、Toggle NAND初始的时候是Async模式,通过发送Set Feature命令后,可以切入ONFi Sync,或者Toggle模式。

Legacy NAND(Async模式)

NVDDR 模式

包括6种速度(Mode 0~5)

频率 NVDDR模式 NVDDR2模式
20MHz NVDDR Mode 0
33MHz NVDDR Mode 1 NVDDR2 Mode 0
40MHz NVDDR2 Mode 1
50MHz NVDDR Mode 2
66MHz NVDDR Mode 3 NVDDR2 Mode 2
83MHz NVDDR Mode 4 NVDDR2 Mode 3
100MHz NVDDR Mode5 NVDDR2 Mode 4
133MHz NVDDR2 Mode 5
166MHz NVDDR2 Mode 6
200MHz NVDDR2 Mode 7
267MHz NVDDR2 Mode 8

NAND 模式的切换

通过发送 SET FEATURE 命令

NVDDR2 模式

包括9种速度(Mode 0~8) 高速情况下,通常使用DQS RE_B差分

Toggle 模式

Toggle 模式多了一根DQS(Data Strobe)线,在DQS的上升 & 下降沿,对 通常,Toggle NAND能够兼容Legacy NAND的操作,

NAND空闲区

OOB(Out-of-Band)/Spare region

NAND Read Retry技术

NAND在一定的擦写次数后,其读取的电平阈值会发生漂移。因此,可以通过更改参考电压的方式延长闪存使用寿命。

Meta D0 BCH D1 BCH D2 BCH D3 BCH D4 BCH D5 BCH D6 BCH D7 BCH
32B 128B ? 128B ? 128B ? 128B ? 128B ? 128B ? 128B ? 128B ?

i.MX6 的NAND控制器

i.MX6内建了GPMI(General Purpose Media Interface) NAND控制器,以及BCH硬件ECC加速模块进行NAND纠错。
GPMI模块兼容ONFi 2.2以及Toggle NAND协议。
此外,i.MX6的BCH模块最多能纠错62位数据(数据长度<1900字节)。

BCH控制器

BCH的主要功能是对NAND的数据进行纠错处理。

NAND BCH Layout

|                          P                            |
|<----------------------------------------------------->|
|                                                       |
|                                        (Block Mark)   |
|                      P'                      |      | |     |
|<-------------------------------------------->|  D   | |  O' |
|                                              |<---->| |<--->|
V                                              V      V V     V
+---+----------+-+----------+-+----------+-+----------+-+-----+
| M |   data   |E|   data   |E|   data   |E|   data   |E|     |
+---+----------+-+----------+-+----------+-+----------+-+-----+
                                               ^              ^
                                               |      O       |
                                               |<------------>|
                                               |              |
简写 说明
G gf_len Galois Field长度
E ecc_strength ECC纠错强度(可纠错的数据bit数?)
M metadata_size metadata长度(Byte)
C ecc_chunk_size 被校验的数据块长度(Byte),例如512B。第一块数据块包含了metadata因此第一块的长度比该数值稍大些
N ecc_chunk_count 被校验的数据块个数(包括第一个?)
P' data_page_size datapage大小
P 实际使用的page大小(Byte)
O oob长度(Byte)
O' 空闲的oob
D BBM与ecc_chunk(data)位置结尾的差值

ECC纠错能力计算

计算公式:

NAND纠错满足如下关系
    (E*G*N)/8 <= (O - M)
不等式整理得:
    E <= (O - M)*8/(G*N)

GF13(BCH40)的生成多项式是:x^9+1
可以对<=900 Bytes数据纠错(所以,C=512B时采用GF13)

GF14(BCH20)的生成多项式是:x^10 + x
可以对<=1900 Bytes数据纠错(所以,C=1024B时采用GF14)

BCH 默认参数的计算

ecc_chunk_size=1 << `ECC Codeword size`
if (ecc_chunk_size == 512)
    gf_len = 13
if (ecc_chunk_size == 1024)
    gf_len = 14
ecc_strength = roundup(`ECC Codeword size`, 2)
metadata_size=10
ecc_chunk_count = `data_page_size`/ecc_chunk_size
P = 'data_page_size` + metadata_size + (gf_len*ecc_strength*ecc_chunk_count)/8

交换BBM的位置计算

在BCH向GPMI写入NAND数据之前,需要将写入BBM位置处的Byte复制到Metadata头部,并且在BBM位置仍然保留原来的BBM;这样就不会破坏原本该block上的坏块标记信息。
同时,需要保证BBM的位置落在data里,而不是ECC里(因为data里存放的数据是raw的,这样在decode完一个page的NAND数据后,BBM位置的数据就可以被Metadata头部的数据替换回来。 NAND驱动仍应对BBM在BCH Layout上的位置进行检查,防止其落入ECC的位置。

计算公式:

D = (gf_len*ecc_strength*(ecc_chunk_count-1))/8 + metadata_size

Async模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0..............1.'},
  {name: 'R/B#', wave: 'x.0..........10..x.'},
  {name: 'CLE', wave: 'x.010......10....x.'},
  {name: 'ALE', wave: 'x.0...1..0.......x.'},
  {name: 'RE#', wave: '1.............n.|h.'},
  {name: 'WE#', wave: '1..nh.n.|nh........', phase: 0.5},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|=.|x.', data: ['00', 'ADDR', '30', 'DATA']},
]}

Sync模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0................1.'},
  {name: 'R/B#', wave: 'x.0..........10....x.'},
  {name: 'CLE', wave: 'x.010......10.1....x.'},
  {name: 'ALE', wave: 'x.0...1..0....1....x.'},
  {name: 'CLK(RE#)', wave: 'n....|..|.......n.|..'},
  {name: 'WR#(WE#)', wave: 'x..1x.1..x.1xx0....x.'},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|====|x.', data: ['00', 'ADDR', '30', 'D0', 'D1', 'D2']},
  {name: 'DQS', wave: 'x.............0P....x', phase: 0.5},
]}

Toggle模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0................1.'},
  {name: 'R/B#', wave: 'x.0..........10....x.'},
  {name: 'CLE', wave: 'x.010......10......x.'},
  {name: 'ALE', wave: 'x.0...1..0.........x.'},
  {name: 'RE#', wave: '1.............01010|1', phase: 0.5},
  {name: 'WE#', wave: '1..nh.n.|h.nh........'},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|====|x.', data: ['00', 'ADDR', '30', 'D0', 'D1', 'D2']},
  {name: 'DQS', wave: 'z.............0101|z.'},
]}

部分i.MX芯片的ECC纠错能力

芯片 BCH ECC能力
imx23 20
imx28 20
imx6q 40
imx6sx 62

测试常用 NAND 列表

Env NAND pagesize(Byte) blockcount pageperblk manufacturer devicecode iddata MB
RTL hy27ss16121a 256+8 4096 32 0xAD 0x46 32
RTL k9f5616q0c 256+8 2048 32 0xEC 0x45 16
RTL tc58dvm82f1ft00 256+8 2048 32 0x98 0x75 0x20 16
RTL hy27ss08121a 512+16 4096 32 0xAD 0x36 64
RTL k9f5608q0c 512+16 2048 32 0xEC 0x35 32
RTL nand512w3a2 512+16 4096 32 0x20 0x76 0x00, 0x00 64
RTL tc58dvg02a1fti0 512+16 8192 32 0x98 0x79 0x20 128
RTL hy27uf162g2m 1K+32 2048 64 0xAD 0xCA 0x00, 0x55 128
RTL k9f1g16u0m 1K+32 1024 64 0xEC 0xC1 0x00, 0x55 64
RTL mt29f2g16aab 1K+32 2048 64 0x2C 0xCA 0x00, 0x55 128
RTL tc58nyg0d9bxgj5 1K+32 512 128 0x98 0xB1 0x00, 0x61 64
RTL hy27uf082g2m 2K+64 2048 64 0xAD 0xDA 0x00, 0x15 256
RTL k9f1g08u0m 2K+64 1024 64 0xEC 0xF1 0x00, 0x15 128
RTL k9k8g08u0m 2K+64 8192 64 0xEC 0xD3 0x51, 0x95, 0x58 1024
RTL mt29f2g08aab 2K+64 2048 64 0x2C 0xDA 0x15, 0x15 256
RTL nand02gw3b 2K+64 2048 64 0x20 0xDA 0x00, 0x15 256
RTL nand04gw3b 2K+64 4096 64 0x20 0xDC 0x00, 0x15 512
RTL tc58nvg0s3aft05 2K+64 1024 64 0x98 0xF1 0x80, 0x95, 0x40 128
RTL k9gag08u0m 4K+128 4096 128 0xEC 0xD5 0x14, 0xB6, 0x74 2048
RTL tc58nvg4d1dtg00 4K+218 4096 128 0x98 0xD5 0x00, 0x3A, 0x00 2048
RTL k9kbgd8x1m 8K+512 4152 64 0xEC 0xD5 0x10, 0x66, 0x34, 0xC2 2076
RTL k9gbg08u0m 8K+436 4152 128 0xEC 0xD7 0x94, 0x72, 0x54, 0x42 4152
RTL k9gbgd8u0m 8K+512 4152 128 0xEC 0xD7 0x14, 0x76, 0x54, 0xC2 4152
RTL k9fagd8u0m 8K+640 4152 64 0xEC 0xD5 0x10, 0x66, 0x34, 0xC2 2076
RTL toggle20_k9gcgy8s0a 8K+640 8192 128 0xEC 0xAE 0xE5, 0x7E, 0x7C, 0xC4 8192
RTL sdtnqgama_008ga 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0xD7 8528
RTL sdtnrgama_008gp 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0x50 8528
RTL sdtnrgama_008g 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0x50 8528
MX8QXPLPD4 MT29F128G08CBCCBH6 16K+1872 512 0x2C 0x84 0x64 0x54 0xa9

参考

ONFi Specification
Raw NAND ECC
How Micron FortisFlash Technology Improves Performance and Endurance
gpmi-nand.c