2012-03-30 22:33 PRU 扩展4路串口

来源:互联网 发布:复制信息再在淘宝打开 编辑:程序博客网 时间:2024/06/06 10:43

跟踪波特率的产生,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更与串口驱动打交道

原创粉丝点击