diff --git a/Hardware/k210/uarths.md b/Hardware/k210/uarths.md new file mode 100644 index 0000000..1f7077a --- /dev/null +++ b/Hardware/k210/uarths.md @@ -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置0,ie.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寄存器里获取吗? \ No newline at end of file diff --git a/Hardware/k210/系统控制器.md b/Hardware/k210/系统控制器.md index 2e33b59..c88be26 100644 --- a/Hardware/k210/系统控制器.md +++ b/Hardware/k210/系统控制器.md @@ -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_enable,1为使能,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,绕过对应pll;0,不绕过对应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,绕过对应pll;0,不绕过对应pll | + | pll2->pll_ckin_sel2 | 0, 1, 2 | 0,IN0;1,PLL0;2,PLL1 | + | 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的具体作用。