跟踪波特率的产生,PRU——Soft-uart data struct :
257 typedef struct {
258 unsigned char TXSerializer;
259 /* 软串口的传输引脚号对应MCASP引脚 0-15 */
260 unsigned char RXSerializer;
261 /* 软串口的接收引脚号 0-15 */
262 unsigned short txClkDivisor;
/* 分频值(CLKXDIV*HCLKDIV)用于产生接收波特率 300-230400 */
263 unsigned short rxClkDivisor;
264 unsigned char txBitsPerChar;
/* 数据位长度(6-12)+1bit_st+1bit_stop
265 unsigned char rxBitsPerChar;
266 unsigned char Oversampling;
/* 采样率8X/16X */
267 unsigned char BIIntrMask;
/* Break Indicator 中断掩码 */
268 unsigned char FEIntrMask;
/* Framing Error中断掩码 */
269 } suart_config;
275
276 typedef struct {
277 unsigned short uartNum;
/* 串口编号 1-16 */
278 unsigned short uartType;
279 /* 串口类型:全双工,半双工 */
280 unsigned short uartTxChannel;
281 /* 与TXSerializer作用一样 */
282 unsigned short uartRxChannel;
283
284 unsigned short uartStatus;
285 /* 串口状态 ,被使用或空,防止重复打开 */
286 } suart_struct_handle;
波特率由unsigned short txClkDivisor,rxClkDivisor保存设置,系统时钟首先要设置MCASP的时钟:
MCASP模块需要两个时钟module clk和TX/RX基准时钟
module CLK 由CFGCHIP[ASYNC3_CLKSRC]决定,=1采用PLL1_SYSCLK2,=0采用PLL0_SYSCLK2
TX/TX基准时钟可由内部或外部时钟输出,可通过配置ACLKRCTL,AHCLKRCTL,ACLKXCTL,AHCLKXCTLPS,这里采用内部时钟为PLL0_AUXCLK(24MHZ).
163 mcasp0Regs->ACLKRCTL = 0x000000A0;
164 mcasp0Regs->AHCLKRCTL = 0x00008000;
171 // configure transmit registers.
172 mcasp0Regs->XMASK = 0x0000FFFF;
173 mcasp0Regs->XFMT = 0x00002078;
174 mcasp0Regs->AFSXCTL = 0x00000012;
175 mcasp0Regs->ACLKXCTL = 0x000000E0;
176 mcasp0Regs->AHCLKXCTL = 0x00008000;
PRU和MCASP module采用的时钟为PLL0_SYSCLK2 == 150MHZ,在探测阶段获得,并使能。UARTCLK=MCASP
short pru_softuart_setbaud()可以设置波特率,PRU DRAM传送给固件。
387 /* Set the baud */
388 if (SUART_SUCCESS !=
389 pru_softuart_setbaud(&soft_uart->suart_hdl[port->line],
390 SUART_DEFAULT_BAUD / baud,
391 SUART_DEFAULT_BAUD / baud))
392 __suart_err("failed to set baud to: %d\n", baud);
参数:@115200/
150MHZ/16/
374 /*
375 * Ask the core to calculate the divisor for us.
376 */
377 baud = uart_get_baud_rate(port, termios, old,
378 port->uartclk / 16 / 0xffff,
379 port->uartclk / 16);
MaASP TX/RX时钟:
short suart_mcasp_tx_baud_set(unsigned int txBaudValue, arm_pru_iomap * pru_arm_iomap);
269 short suart_mcasp_rx_baud_set(unsigned int rxBaudValue,
270 unsigned int oversampling,
271 arm_pru_iomap * pru_arm_iomap);
分别设置ACLKR/XCTL,AHCLKR/XCTL寄存器。控制MCASP引脚基准时钟。
以TX为例:
55 unsigned int lt_tx_baud_rate[][SUART_TRX_DIV_CONF_SZ] = {
56 /*BaudRate, Divisor, CLKXDIV, HCLKXDIV */
57 {300, 80000, 24, 3200},
58 {600, 40000, 15, 2500},
59 {1800, 13333, 10, 1212},
60 {2400, 10000, 4, 2000},
61 {4800, 5000, 1, 2500},
62 {7200, 3333, 0, 3333},
63 {9600, 2500, 0, 2500},
64 {14400, 1666, 0, 1666},
65 {19200, 1250, 0, 1250},
66 {38400, 625, 0, 625},
67 {57600, 416, 0, 416},
68 {115200, 208, 0, 208},
69 {230400, 104, 0, 104}
70 };
若选择baud rate:115200,则CLKXDIV = 0,HCLK = 208.
139 void suart_mcasp_config(unsigned int mcasp_addr,
140 unsigned int txBaudValue,
141 unsigned int rxBaudValue,
142 unsigned int oversampling,
143 arm_pru_iomap * pru_arm_iomap);
在这个函数进行了配置,同时这个函数也进行McASP端口的配置。
具体配置:
1.hawkboard McASP只有9-12为空闲,这里配置9&11为RX,10&12为TX
202 //Configure all AXR[n] as McASP pins
203 mcasp0Regs->PFUNC = CSL_MCASP_PFUNC_RESETVAL;//0x0,McASP pins
204 mcasp0Regs->PDOUT = 0xFFFF;
205
206 //Configure PDIR for test purposes
207 //set frame sync, clocks as output, AXR10,12 as output, AXR9,11
208 mcasp0Regs->PDIR = MCASP_PDIR_VAL; // has receiver configuration as well
209 mcasp0Regs->PDOUT = 0xFFFF;
PDIR寄存器配置:
87 #define MCASP_PDIR_VAL ( \
88 CSL_MCASP_PDIR_AFSR_OUTPUT<<CSL_MCASP_PDIR_AFSR_SHIFT | \
89 CSL_MCASP_PDIR_AHCLKR_OUTPUT<<CSL_MCASP_PDIR_AHCLKR_SHIFT | \
90 CSL_MCASP_PDIR_ACLKR_OUTPUT<<CSL_MCASP_PDIR_ACLKR_SHIFT | \
91 CSL_MCASP_PDIR_AFSX_OUTPUT<<CSL_MCASP_PDIR_AFSX_SHIFT | \
92 CSL_MCASP_PDIR_AHCLKX_OUTPUT<<CSL_MCASP_PDIR_AHCLKX_SHIFT | \
93 CSL_MCASP_PDIR_ACLKX_OUTPUT<<CSL_MCASP_PDIR_ACLKX_SHIFT | \
94 CSL_MCASP_PDIR_AXR10_OUTPUT<<CSL_MCASP_PDIR_AXR8_SHIFT | \
95 CSL_MCASP_PDIR_AXR9_INPUT<<CSL_MCASP_PDIR_AXR7_SHIFT | \
96 CSL_MCASP_PDIR_AXR12_OUTPUT<<CSL_MCASP_PDIR_AXR10_SHIFT | \
97 CSL_MCASP_PDIR_AXR11_INPUT<<CSL_MCASP_PDIR_AXR9_SHIFT)
2.这里只配置了9-12 pins,故只有两路串口 还需修改驱动中最大串口数:
//42 #define NR_SUART 3
#define NR_SUART 2
还要修改PRU_串口结构体中对于收发引脚的绑定:
39 #define PRU_SUART1_CONFIG_DUPLEX (ePRU_SUART_HALF_TX | ePRU_SUART_HALF_RX)
40 #define PRU_SUART1_CONFIG_RX_SER (PRU_SUART_SERIALIZER_9)
41 #define PRU_SUART1_CONFIG_TX_SER (PRU_SUART_SERIALIZER_10)
42
43 #define PRU_SUART2_CONFIG_DUPLEX (ePRU_SUART_HALF_TX | ePRU_SUART_HALF_RX)
44 #define PRU_SUART2_CONFIG_RX_SER (PRU_SUART_SERIALIZER_11)
45 #define PRU_SUART2_CONFIG_TX_SER (PRU_SUART_SERIALIZER_12)
当驱动试图打开软串口时,系统会将对应的串口绑定到两个端口TX/RX:
140 case PRU_SUART_UART1:
141 if (gUartStatuTable[PRU_SUART_UART1 - 1] ==
142 ePRU_SUART_UART_IN_USE) {//设备被使用
143 status = SUART_UART_IN_USE;
144 return status;
145 } else {
146 hSuart->uartStatus = ePRU_SUART_UART_IN_USE;
147 hSuart->uartType = PRU_SUART1_CONFIG_DUPLEX;
148 hSuart->uartTxChannel = PRU_SUART1_CONFIG_TX_SER;
149 hSuart->uartRxChannel = PRU_SUART1_CONFIG_RX_SER;
150
151 gUartStatuTable[PRU_SUART_UART1 - 1] =
152 ePRU_SUART_UART_IN_USE;
153 }
。。。
这里串口0.分配来上面定义9,10端口作为收发引脚。另外在suart_config中也进行来绑定。
635 if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART1) {
636 pru_suart_config.TXSerializer = PRU_SUART1_CONFIG_TX_SER;
637 pru_suart_config.RXSerializer = PRU_SUART1_CONFIG_RX_SER;
663 /* Some defaults to startup. reconfigured by terimos later */
664 pru_suart_config.txClkDivisor = 1;
665 pru_suart_config.rxClkDivisor = 1;
到这里suart_config,suart_struct_handle的结构的作用基本搞清楚了。
suart_config是与PRU固件密切相关的结构体,在请求打开端口时,会将该结构的内容到PRU DRAM中,PRU固件会读取这些区域的参数。
suart_struct_handle 该结构是一个全局结构,在操作具体时会根据uartNum成员辨别不同的串口。
suart_config 更与firmware打交道
suart_struct_handle更与串口驱动打交道
2012-03-30 22:33 PRU 扩展4路串口
最新推荐文章于 2021-11-03 20:51:58 发布