update k210/系统控制器.md, add k210/uarths.md

This commit is contained in:
shzhxh 2019-06-10 09:46:55 +08:00
parent e7b6dde91c
commit 8184bb5fef
2 changed files with 91 additions and 28 deletions

65
Hardware/k210/uarths.md Normal file
View File

@ -0,0 +1,65 @@
#### 寄存器
共包含7个32位寄存器
| 编号 | 名称 | 描述 |
| ---- | ------ | ------------------------------------------------------------ |
| 0 | txdata | 传递数据。[0:7]数据,[8:30]为0[31]满状态 |
| 1 | rxdata | 接收数据。[0:7]数据,[8:30]为0[31]空状态 |
| 2 | txctrl | 传递控制。[0]tx使能[1]0一个停止位,1二个停止位[2:15]保留,[16:18]中断触发器的分频值,[19:31]保留 |
| 3 | rxctrl | 接收控制。[0]tx使能[1:15]保留,[16:18]中断触发器的分频值,[19:31]保留 |
| 4 | ie | 中断使能。[0]0禁止发送,1使能发送[1]0禁止接收,1使能接收[2:31]为0 |
| 5 | ip | 中断pending。[0]小于txcnt[1]大于rxcnt[2:31]为0 |
| 6 | div | 波特率divisor。[0:15]波特率divisor[16:31]为0 |
#### 功能
- 初始化`uarths_init`
设置波特率因子(div.div)为(CPU频率)/(115200-1)
将tx和rx使能位置1(txctrl.txen、rxctrl.rxen)
将tx和rx分频值置0(txctrl.txcnt、rxctrl.rxcnt)
将ip.txwn和ip.rxwm置1
将ie.txwm置0ie.rxwm置1
- 传递和接收字符`uarths_[putchar | getchar]`
传递字符当txdata.full为1表示还有未传完的数据只有当其为0时才可以写入数据。当txdata.full为0时将要输入的字符串写入txdata.data。
接收字符当rxdata.empty为1时表示无数据可接收当其为0时才表示rxdata.data为接收到的字符。
- 传递字符串`uarths_puts`
使用`uarths_putchar`以0作为终止条件。
- 设置中断回调`uarths_set_irq`
- 接收和发送数据`uarths_[receive | send]_data`
与传递和接收字符类似只是指定了数据的长度这样就可以使用for语句了。
- 获取中断模式`uarths_get_interrupt_mode`
中断模式有3种发送(1)、接收(2)、发送和接收(3)。是从ip寄存器的rxwm和txwm获取的。
- 设置波特率和停止位`uarths_config`
通过设置div.div为(CPU时钟频率)/(波特率-1)来使波特率生效。
通过设置txctrl.nstop来设置停止位。
- 设置中断条件`uarths_set_interrupt_cnt`
当为发送模式则设置txctrl.txcnt来设置中断条件。
当为接收模式则设置rxctrl.rxcnt来设置中断条件。
当为发送和接收模式则设置txctrl.txcnt和rxctrl.rxcnt来设置中断条件。
#### 问题
1. 不理解中断模式为什么要从ip寄存器里获取不应该是从ie寄存器里获取吗

View File

@ -8,9 +8,7 @@
一个总线协议,几乎成为一种标准的片上总线结构。主要用于低带宽的外设连接。
#### 系统控制器
##### 系统控制器的寄存器
#### 系统控制器的寄存器
系统控制器是个外设它负责所有与系统相关的外设的设置。它的32个32位寄存器都映射在内存里。
@ -24,19 +22,19 @@
| 5 | resv5 | 保留 |
| 6 | pll_lock | PLL锁测试器。其中pll_lock0~2均只读pll_lock0=3则pll0已锁pll_lock1=1则pll1已锁pll_lock2=1则pll2已锁。其中pll_lip_clear0~2用于清空对应pll的slip置1则清空对应pll的slip。 |
| 7 | rom_error | AXI ROM测试器 |
| 8 | clk_sel0 | 时钟选择控制器0。可写其中aclk_sel设置aclk为时钟源其中aclk_divider_sel占用2位控制aclk的阈值其中apb0~2_clk_sel分别占用3位分别控制apb0~2的阈其中spi3_clk_sel设置spi3为时钟源其中timer0~2_clk_sel分别设置timer0~2为时钟源其它为保留位。 |
| 8 | clk_sel0 | 时钟选择控制器0。可写其中aclk_sel设置aclk为时钟源其中aclk_divider_sel占用2位控制aclk的分频值其中apb0~2_clk_sel分别占用3位分别控制apb0~2的分频其中spi3_clk_sel设置spi3为时钟源其中timer0~2_clk_sel分别设置timer0~2为时钟源其它为保留位。 |
| 9 | clk_sel1 | 时钟选择控制器1。可写仅第一位有效spi3_sample_clk_sel将spi3_sample设为时钟源。 |
| 10 | clk_en_cent | 中心时钟使能。可写每一位控制一个时钟使能共用6个位控制cpu, sram0~1, apb0~2其余位保留。其中apb0~2分别控制着若干外设。置1使能置0不使能。 |
| 11 | clk_en_peri | 外部时钟使能。可写每一位控制一个外设的时钟全能。置1使能置0不使能。 |
| 12 | soft_reset | 软重置。可写仅第一位有效。置1重置置0不重置。 |
| 13 | peri-reset | 外重置。可写每一位控制一个外设。置1重置置0不重置。 |
| 14 | clk_th0 | 时钟阈值控制器0。可写控制阈值宽度为4的外设的阈控制的外设有5个sram0~1, ai, dvp, rom |
| 15 | clk_th1 | 时钟阈值控制器1。可写控制阈值宽度为8的外设的阈控制的外设有4个spi0~3 |
| 16 | clk_th2 | 时钟阈值控制器2。可写控制阈值宽度为8的外设的阈控制的外设有3个timer0~2剩余8位为保留位 |
| 17 | clk_th3 | 时钟阈值控制器3。可写控制阈值宽度为16的外设的阈控制的外设有2个i2s0~1_clk_threshold |
| 18 | clk_th4 | 时钟阈值控制器4。可写控制2个阈值宽度为8的外设的阈值i2s0~1_mclk_threshold还控制1个阈值宽度为16的外设的阈i2s2_clk_threshold |
| 19 | clk_th5 | 时钟阈值控制器5。可写控制阈值宽度为8的外设的阈控制的外设有4个i2s2_mclk_threshold, i2c0~2_clk_threshold |
| 20 | clk_th6 | 时钟阈值控制器6。可写控制阈值宽度为8的外设的阈控制的外设有2个wdt0~1_clk_threshold, 剩余16位为保留位 |
| 14 | clk_th0 | 时钟分频值控制器0。可写控制分频值宽度为4的外设的分频控制的外设有5个sram0~1, ai, dvp, rom |
| 15 | clk_th1 | 时钟分频值控制器1。可写控制分频值宽度为8的外设的分频控制的外设有4个spi0~3 |
| 16 | clk_th2 | 时钟分频值控制器2。可写控制分频值宽度为8的外设的分频控制的外设有3个timer0~2剩余8位为保留位 |
| 17 | clk_th3 | 时钟分频值控制器3。可写控制分频值宽度为16的外设的分频控制的外设有2个i2s0~1_clk_threshold |
| 18 | clk_th4 | 时钟分频值控制器4。可写控制2个分频值宽度为8的外设的分频值i2s0~1_mclk_threshold还控制1个分频值宽度为16的外设的分频i2s2_clk_threshold |
| 19 | clk_th5 | 时钟分频值控制器5。可写控制分频值宽度为8的外设的分频控制的外设有4个i2s2_mclk_threshold, i2c0~2_clk_threshold |
| 20 | clk_th6 | 时钟分频值控制器6。可写控制分频值宽度为8的外设的分频控制的外设有2个wdt0~1_clk_threshold, 剩余16位为保留位 |
| 21 | misc | 杂项控制器。有1个1位的sip_dvp_data_enable1为使能0为不使能 |
| 22 | peri | 外设控制器 |
| 23 | spi_sleep | SPI睡眠控制器 |
@ -46,7 +44,7 @@
| 27 | power_sel | IO电源模式选择控制器。可写power_mode_sel0~7共8个1位的项控制8种电源模式1为使能0为不使能其余24位保留 |
| 28-31 | resv28-resv31 | 保留 |
##### 系统控制器的功能
#### 系统控制器的功能
- 外设时钟的使能或取消使能`sysctl_clock_[enable | disable]`
@ -66,12 +64,12 @@
- 时钟对应时钟源的设置与获取`sysctl_clock_[set | get]_clock_select`
| 时钟 | 时钟源 | 意义 |
| ------------------------------------ | ---------- | -------------------------------------------------------- |
| pll0~2->pll_bypass0~2 | 0, 1 | 1绕过对应pll0不绕过对应pll |
| pll2->pll_ckin_sel2 | 0, 1, 2, 3 | |
| clk_sel0寄存器的aclk, spi3, timer0~2 | 0, 1 | 1设置对应设备为时钟源0不设置对应设备为时钟源 |
| clk_sel1->spi3_sample_clk_sel | 0, 1 | 1设置spi3_sample为时钟源0不设置spi3_sample为时钟源 |
| 时钟 | 时钟源 | 意义 |
| ------------------------------------ | ------- | -------------------------------------------------------- |
| pll0~2->pll_bypass0~2 | 0, 1 | 1绕过对应pll0不绕过对应pll |
| pll2->pll_ckin_sel2 | 0, 1, 2 | 0IN01PLL02PLL1 |
| clk_sel0寄存器的aclk, spi3, timer0~2 | 0, 1 | 1设置对应设备为时钟源0不设置对应设备为时钟源 |
| clk_sel1->spi3_sample_clk_sel | 0, 1 | 1设置spi3_sample为时钟源0不设置spi3_sample为时钟源 |
时钟源的设置就是为如上寄存器的相关位指定时钟源。
@ -84,7 +82,7 @@
# nr = pll.clkr + 1
# nf = pll.clkf + 1
# od = pll.clkod + 1
# FIN : 如PLL0~1则为26000000UL如PLL2则从pll2.pll_ckin_sel2获取对应select(可能是SOURCE_IN0, SOURCE_PLL0, SOURCE_PLL1)如SOURCE_IN0则为26000000UL,如SOURCE_PLL0~1则按上述公式再算一遍。
# FIN : 如PLL0~1则为26000000UL如PLL2则从pll2.pll_ckin_sel2获取对应时钟源(可能是SOURCE_IN0, SOURCE_PLL0, SOURCE_PLL1)如SOURCE_IN0则为26000000UL,如SOURCE_PLL0~1则按上述公式再算一遍。
```
- 获取各种设备的基本时钟频率`sysctl_clock_get_freq`
@ -93,14 +91,14 @@
| -------------------------------------------------------- | ------- | ------------------------------------------------------------ |
| **IN0** | | 源频率是26000000UL结果频率与源频率相等 |
| directly under **PLL**时钟域(PLL0~2) | gated | 源频率是对应PLL的频率结果频率与源频率相等 |
| directly under **ACLK**时钟域(CPU, DMA, FFT, ACLK, HCLK) | | 从寄存器clk_sel0的aclk位取对应的值如为0表示没有选择aclk则源频率为IN0的频率如为1表示选择了aclk则源频率的算法为(PLL0的频率)/(2ULL << ACLK的时钟)结果频率与源频率相等 |
| under **ACLK**时钟域(SRAM0~1, ROM, DVP) | gated | 源频率是ACLK的时钟频率结果频率的算法为(源频率)/(设备对应的值 + 1) |
| under **ACLK**时钟域(ABP0~2) | even | 源频率是ACLK的时钟频率结果频率的算法为(源频率)/(设备对应的值 + 1) |
| under **AI**时钟域 | gated | 源频率是PLL1的时钟频率结果频率的算法为(源频率)/(AI的值 + 1) |
| under **I2S**时钟域(I2S0~2) | even | 源频率是PLL2的时钟频率结果频率的算法为(源频率)/(对应设备的值 + 1)/2 |
| under **WDT**时钟域(WDT0~1) | even | 源频率是IN0的时钟频率结果频率的算法为(源频率)/(对应设备的值 + 1)/2 |
| under **PLL0**时钟域(SPI0~2, I2C0~2) | even | 源频率是PLL0的时钟频率结果频率的算法为(源频率)/(对应设备的值 + 1)/2 |
| under **PLL0_SEL**时钟域(SPI3, TIMER0~2) | even | 从寄存器clk_sel0相应的位获取对应的值如为0表示没有选择对应设备的时钟则源频率为IN0的频率如为1表示选择了对应设备的时钟其源频率为PLL0的频率。对于SPI3结果频率的算法是(源频率)/(SPI3的阈值 + 1)/2对于TIMER0~2结果频率的算法是(源频率)/(TIMER2的阈值 + 1)/2 |
| directly under **ACLK**时钟域(CPU, DMA, FFT, ACLK, HCLK) | | 从寄存器clk_sel0的aclk位取对应的值如为0表示没有选择aclk则源频率为IN0的频率如为1表示选择了aclk则源频率的算法为(PLL0的频率)/(2ULL << ACLK的时钟分频)结果频率与源频率相等 |
| under **ACLK**时钟域(SRAM0~1, ROM, DVP) | gated | 源频率是ACLK的时钟频率结果频率的算法为(源频率)/(设备对应的分频值 + 1) |
| under **ACLK**时钟域(ABP0~2) | even | 源频率是ACLK的时钟频率结果频率的算法为(源频率)/(设备对应的分频值 + 1) |
| under **AI**时钟域 | gated | 源频率是PLL1的时钟频率结果频率的算法为(源频率)/(AI的分频值 + 1) |
| under **I2S**时钟域(I2S0~2) | even | 源频率是PLL2的时钟频率结果频率的算法为(源频率)/(对应设备的分频值 + 1)/2 |
| under **WDT**时钟域(WDT0~1) | even | 源频率是IN0的时钟频率结果频率的算法为(源频率)/(对应设备的分频值 + 1)/2 |
| under **PLL0**时钟域(SPI0~2, I2C0~2) | even | 源频率是PLL0的时钟频率结果频率的算法为(源频率)/(对应设备的分频值 + 1)/2 |
| under **PLL0_SEL**时钟域(SPI3, TIMER0~2) | even | 从寄存器clk_sel0相应的位获取对应的值如为0表示没有选择对应设备的时钟则源频率为IN0的频率如为1表示选择了对应设备的时钟其源频率为PLL0的频率。对于SPI3结果频率的算法是(源频率)/(SPI3的分频值 + 1)/2对于TIMER0~2结果频率的算法是(源频率)/(TIMER2的分频值 + 1)/2 |
| under **MISC**时钟域 | even | 无代码,仅注释,目前无任何意义 |
| under **APB0**时钟域(GPIO, UART1~3, FPIOA, SHA) | even | 源频率为APB0的时钟频率结果频率与源频率相等 |
| under **APB1**时钟域(AES, OTP, RTC) | even | 如为AES或OTP则源频率是APB1的时钟频率如为RTC则源频率是IN0的时钟频率。结果频率与源频率相等 |
@ -175,7 +173,7 @@
从**mcycle**获取CPU周期数从`sysctl_clock_get_freq()`获取CPU频率两者相除即为启动到现在所过的时间。
##### 待解决的问题
#### 待解决的问题
- 不知道PLL的具体作用。