LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
suart_utils.c
Go to the documentation of this file.
1 /*
2  * pru/hal/uart/src/suart_utils.c
3  *
4  * Copyright (C) 2010 Texas Instruments Incorporated
5  * Author: Jitendra Kumar <jitendra@mistralsolutions.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation version 2.
10  *
11  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
12  * whether express or implied; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  */
16 
17 /*
18  *====================
19  * Includes
20  *====================
21  */
22 
23 #include "suart_pru_regs.h"
24 #include "omapl_suart_board.h"
25 #include "suart_api.h"
26 #include "suart_utils.h"
27 #include "suart_err.h"
28 #include "pru.h"
29 
30 #include "csl/soc_OMAPL138.h"
31 #include "csl/cslr_dspintc.h"
32 #include "csl/cslr_mcasp.h"
33 #include "csl/cslr_psc_OMAPL138.h"
34 
35 #define SUART_TRX_DIV_CONF_SZ 4
36 
37 static short suart_mcasp_tx_baud_set(unsigned int txBaudValue,
38  arm_pru_iomap * pru_arm_iomap);
39 static short suart_mcasp_rx_baud_set(unsigned int rxBaudValue,
40  unsigned int oversampling,
41  arm_pru_iomap * pru_arm_iomap);
42 
43 /*
44  * Lookup table for TX baud rate
45  * The divisor value is calculated using the formula
46  *
47  * ACLKX = (AUXCLK)/(CLKXDIV * HCLKXDIV)
48  *
49  * Where
50  * CLKXDIV takes values from 1-32
51  * HCLKXDIV takes values from 1-4096
52  * Here
53  * AUXCLK = 24MHz
54  */
55 
57  /*BaudRate, Divisor, CLKXDIV, HCLKXDIV */
58  {300, 80000, 24, 3200},
59  {600, 40000, 15, 2500},
60  {1800, 13333, 10, 1212},
61  {2400, 10000, 4, 2000},
62  {4800, 5000, 1, 2500},
63  {7200, 3333, 0, 3333},
64  {9600, 2500, 0, 2500},
65  {14400, 1666, 0, 1666},
66  {19200, 1250, 0, 1250},
67  {38400, 625, 0, 625},
68  {57600, 416, 0, 416},
69  {115200, 208, 0, 208},
70  {230400, 104, 0, 104}
71 };
72 
73 /*
74  * Lookup table for RX baud rate for 8 bit oversampling
75  * The divisor value is calculated using the formula
76  *
77  * ACLKR = (AUXCLK)/(CLKRDIV * HCLKRDIV) * Oversampling
78  *
79  * Where
80  * CLKRDIV takes values from 1-32
81  * HCLKRDIV takes values from 1-4096
82  * Here
83  * AUXCLK = 24MHz
84  */
86 /*BaudRate, Divisor, CLKXDIV, HCLKXDIV */
87  {300, 10000, 4, 2000},
88  {600, 5000, 1, 2500},
89  {1800, 1667, 0, 1667},
90  {2400, 1250, 0, 1250},
91  {7200, 417, 0, 417},
92  {4800, 625, 0, 625},
93  {9600, 312, 0, 312},
94  {14400, 208, 0, 208},
95  {19200, 156, 0, 156},
96  {38400, 78, 0, 78},
97  {57600, 52, 0, 52},
98  {115200, 26, 0, 26},
99  {230400, 13, 0, 13}
100 };
101 
102 /*
103  * Lookup table for RX baud rate for 16 bit oversampling
104  * The divisor value is calculated using the formula
105  *
106  * ACLKR = (AUXCLK)/(CLKRDIV * HCLKRDIV) * Oversampling
107  *
108  * Where
109  * CLKRDIV takes values from 1-32
110  * HCLKRDIV takes values from 1-4096
111  * Here
112  * AUXCLK = 24MHz
113  */
115 /*BaudRate, Divisor, CLKXDIV, HCLKXDIV */
116  {300, 5000, 1, 2500},
117  {600, 2500, 0, 2500},
118  {1800, 833, 0, 833},
119  {2400, 625, 0, 625},
120  {4800, 312, 0, 312},
121  {7200, 208, 0, 208},
122  {9600, 156, 0, 156},
123  {14400, 104, 0, 104},
124  {19200, 78, 0, 78},
125  {38400, 39, 0, 39},
126  {57600, 26, 0, 26},
127  {115200, 13, 0, 13},
128  {230400, 6, 0, 6}
129 };
130 
131 /*
132  *====================
133  * API implementations
134  *====================
135  */
136 /*
137  * McASP configuration routine
138  */
139 
140 void suart_mcasp_reset (arm_pru_iomap * pru_arm_iomap)
141 {
142 
143  CSL_McaspRegsOvly mcasp0Regs = (CSL_McaspRegsOvly) pru_arm_iomap->mcasp_io_addr;; //CSL_MCASP_0_CTRL_REGS;
144 
145  // reset mcasp.
146  mcasp0Regs->GBLCTL = 0;
147  mcasp0Regs->RGBLCTL = 0;
148  mcasp0Regs->XGBLCTL = 0;
149  mcasp0Regs->XSTAT = 0x0000FFFF; // Clear all
150  mcasp0Regs->RSTAT = 0x0000FFFF; // Clear all
151 
152 }
153 
154 void suart_mcasp_config(unsigned int mcasp_addr,
155  unsigned int txBaudValue,
156  unsigned int rxBaudValue,
157  unsigned int oversampling,
158  arm_pru_iomap * pru_arm_iomap)
159 {
160  CSL_McaspRegsOvly mcasp0Regs = (CSL_McaspRegsOvly) mcasp_addr; //CSL_MCASP_0_CTRL_REGS;
161 
162  // reset mcasp.
163  mcasp0Regs->GBLCTL = 0;
164  mcasp0Regs->RGBLCTL = 0;
165  mcasp0Regs->XGBLCTL = 0;
166 
167  // configure receive registers.
168  if ((SUART_8X_OVRSMPL == oversampling) || (0 == oversampling)){
169  mcasp0Regs->RMASK = 0x000000FF;
170  mcasp0Regs->RFMT = 0x0000A038; //slot size 8 bits , RPAD = 1.
171  }
172  if(SUART_16X_OVRSMPL == oversampling){
173  mcasp0Regs->RMASK = 0x0000FFFF;
174  mcasp0Regs->RFMT = 0x0000A078;
175  }
176 
177  mcasp0Regs->AFSRCTL = 0x00000002; //burst mode
178  mcasp0Regs->ACLKRCTL = 0x000000A0;
179  mcasp0Regs->AHCLKRCTL = 0x00008000;
180  suart_mcasp_rx_baud_set(rxBaudValue, oversampling, pru_arm_iomap);
181 
182  mcasp0Regs->RTDM = 0x00000001;
183  mcasp0Regs->RINTCTL = 0x00000002;
184  mcasp0Regs->RCLKCHK = 0x00FF0008;
185 
186  // configure transmit registers.
187  mcasp0Regs->XMASK = 0x0000FFFF;
188  mcasp0Regs->XFMT = 0x00002078;
189  mcasp0Regs->AFSXCTL = 0x0000002; // Burst mode
190  mcasp0Regs->ACLKXCTL = 0x000000E0;
191  mcasp0Regs->AHCLKXCTL = 0x00008000;
192 
193  suart_mcasp_tx_baud_set(txBaudValue, pru_arm_iomap);
194 
195  mcasp0Regs->XTDM = 0x00000001;
196  mcasp0Regs->XINTCTL = 0x00000002;
197  mcasp0Regs->XCLKCHK = 0x00FF0008;
198 
199  //Serializer as a transmitter
200  mcasp0Regs->SRCTL0 = 0x000c;
201  mcasp0Regs->SRCTL1 = 0x000c;
202  mcasp0Regs->SRCTL2 = 0x000c;
203  mcasp0Regs->SRCTL3 = 0x000c;
204  mcasp0Regs->SRCTL4 = 0x000c;
205  mcasp0Regs->SRCTL5 = 0x000c;
206  mcasp0Regs->SRCTL6 = 0x000c;
207  mcasp0Regs->SRCTL7 = 0x000c;
208  mcasp0Regs->SRCTL8 = 0x000c;
209  mcasp0Regs->SRCTL9 = 0x000c;
210  mcasp0Regs->SRCTL10 = 0x000c;
211  mcasp0Regs->SRCTL11 = 0x000c;
212  mcasp0Regs->SRCTL12 = 0x000c;
213  mcasp0Regs->SRCTL13 = 0x000c;
214  mcasp0Regs->SRCTL14 = 0x000c;
215  mcasp0Regs->SRCTL15 = 0x000c;
216 
217  //Configure all AXR[n] as McASP pins
218 
219  /*
220  * Setting all TX MCASP AXR[n] Pin mapped to Even Serializer number (0,2,4,6,8,10,12,14)
221  * to GPIO Mode by default. During setting the serializer to TX mode in PRU assembly code, the
222  * MCASP AXR[n] Pin would get configured to MCASP mode of operation, before Actual Data Transfer.
223  */
224 
225  //Setting all TX Pin to GPIO Mode by default
226  mcasp0Regs->PFUNC = (CSL_MCASP_PFUNC_RESETVAL) |
231 
232  mcasp0Regs->PDOUT = 0xFFFF;
233 
234  // config pin function and direction.
235  mcasp0Regs->PDIR = 0x00000000;
236  mcasp0Regs->PDIR = (1 << PRU_SUART1_CONFIG_TX_SER)|(1 << PRU_SUART2_CONFIG_TX_SER)|
240  (MCASP_PDIR_VAL);
241 
242  mcasp0Regs->PDOUT = 0xFFFF;
243 
244  mcasp0Regs->DITCTL = 0x00000000;
245  mcasp0Regs->DLBCTL = 0x00000000;
246  mcasp0Regs->AMUTE = 0x00000000;
247 
248  mcasp0Regs->XSTAT = 0x0000FFFF; // Clear all
249  mcasp0Regs->RSTAT = 0x0000FFFF; // Clear all
250 }
251 
252 void suart_mcasp_tx_serialzier_set(unsigned int serializerNum,
253  arm_pru_iomap * pru_arm_iomap)
254 {
255  CSL_McaspRegsOvly mcasp0Regs =
256  (CSL_McaspRegsOvly) pru_arm_iomap->mcasp_io_addr;
257 
258  mcasp0Regs->PFUNC |= (0x1 << serializerNum);
259 }
260 
261 /*
262  * mcasp TX buard rate setting routine
263  */
264 short suart_mcasp_tx_baud_set(unsigned int txBaudValue,
265  arm_pru_iomap * pru_arm_iomap)
266 {
267  unsigned int clkDivVal;
268  unsigned int loopCnt;
269  short status = SUART_SUCCESS;
270  short foundVal = SUART_FALSE;
271 
272  CSL_McaspRegsOvly mcasp0Regs =
273  (CSL_McaspRegsOvly) pru_arm_iomap->mcasp_io_addr;
274 
275  /* Search the supported baud rate in the table */
276  for (loopCnt = 0; loopCnt < SUART_NUM_OF_BAUDS_SUPPORTED; loopCnt++) {
277  if (txBaudValue == lt_tx_baud_rate[loopCnt][0]) {
278  foundVal = SUART_TRUE;
279  break;
280  }
281  }
282  if (foundVal == SUART_TRUE) {
283  clkDivVal = lt_tx_baud_rate[loopCnt][2];
284 
285  mcasp0Regs->ACLKXCTL |=
287  clkDivVal = lt_tx_baud_rate[loopCnt][3]; /* starts from 0 */
288  mcasp0Regs->AHCLKXCTL |=
290  } else {
291  return SUART_INVALID_TX_BAUD;
292  }
293  return (status);
294 }
295 
296 /*
297  * mcasp RX buard rate setting routine
298  */
299 short suart_mcasp_rx_baud_set(unsigned int rxBaudValue,
300  unsigned int oversampling,
301  arm_pru_iomap * pru_arm_iomap)
302 {
303  unsigned int clkDivVal;
304  unsigned int loopCnt;
305  short status = SUART_SUCCESS;
306  short foundVal = SUART_FALSE;
307 
308  CSL_McaspRegsOvly mcasp0Regs =
309  (CSL_McaspRegsOvly) pru_arm_iomap->mcasp_io_addr;
310 
311  if (oversampling == SUART_8X_OVRSMPL) {
312  for (loopCnt = 0; loopCnt < SUART_NUM_OF_BAUDS_SUPPORTED;
313  loopCnt++) {
314  if (rxBaudValue == lt_rx_8x_baud_rate[loopCnt][0]) {
315  clkDivVal = lt_rx_8x_baud_rate[loopCnt][2];
316  mcasp0Regs->ACLKRCTL |=
317  clkDivVal <<
319  clkDivVal = lt_rx_8x_baud_rate[loopCnt][3] - 1; /* starts from 0 */
320  mcasp0Regs->AHCLKRCTL |=
321  clkDivVal <<
323  foundVal = SUART_TRUE;
324  break;
325  }
326  }
327  } else if (oversampling == SUART_16X_OVRSMPL) {
328  for (loopCnt = 0; loopCnt < SUART_NUM_OF_BAUDS_SUPPORTED;
329  loopCnt++) {
330  if (rxBaudValue == lt_rx_16x_baud_rate[loopCnt][0]) {
331  clkDivVal = lt_rx_16x_baud_rate[loopCnt][2];
332  mcasp0Regs->ACLKRCTL |=
333  clkDivVal <<
335  clkDivVal = lt_rx_16x_baud_rate[loopCnt][3] - 1; /* starts from 0 */
336  mcasp0Regs->AHCLKRCTL |=
337  clkDivVal <<
339  foundVal = SUART_TRUE;
340  break;
341  }
342  }
343  } else if (oversampling == 0) {
344  for (loopCnt = 0; loopCnt < SUART_NUM_OF_BAUDS_SUPPORTED;
345  loopCnt++) {
346  if (rxBaudValue == lt_tx_baud_rate[loopCnt][0]) {
347  clkDivVal = lt_tx_baud_rate[loopCnt][2];
348  mcasp0Regs->ACLKRCTL |=
349  clkDivVal <<
351  clkDivVal = lt_tx_baud_rate[loopCnt][3];
352  mcasp0Regs->AHCLKRCTL |=
353  clkDivVal <<
355  foundVal = SUART_TRUE;
356  break;
357  }
358  }
359  } else {
361  }
362 
363  if (foundVal != SUART_TRUE) {
364  return SUART_INVALID_RX_BAUD;
365  }
366 
367  return (status);
368 
369 }
370 
371 /*
372  * mcasp buard rate setting routine
373  */
374 short suart_asp_baud_set(unsigned int txBaudValue,
375  unsigned int rxBaudValue,
376  unsigned int oversampling,
377  arm_pru_iomap * pru_arm_iomap)
378 {
379  short status = SUART_SUCCESS;
380 
381  status = suart_mcasp_tx_baud_set(txBaudValue, pru_arm_iomap);
382  status =
383  suart_mcasp_rx_baud_set(rxBaudValue, oversampling, pru_arm_iomap);
384 
385  return (status);
386 
387 }
388 
389 /*
390  * mcasp deactivate the selected serializer
391  */
392 short suart_asp_serializer_deactivate (unsigned short u16srNum,
393  arm_pru_iomap * pru_arm_iomap)
394 {
395  short status = SUART_SUCCESS;
396  CSL_McaspRegsOvly mcasp0Regs =
397  (CSL_McaspRegsOvly) pru_arm_iomap->mcasp_io_addr;
398  unsigned int * pu32SrCtlAddr = NULL;
399 
400  if (u16srNum > 15)
401  {
402  status = SUART_INVALID_SR_NUM ;
403  }
404  else
405  {
406  pu32SrCtlAddr = (unsigned int *)&(mcasp0Regs->SRCTL0);
407  pu32SrCtlAddr += u16srNum;
408  * (pu32SrCtlAddr) = 0x000C;
409  }
410 
411  return (status);
412 
413 }
414 
415 #if !(defined CONFIG_OMAPL_SUART_MCASP) || (CONFIG_OMAPL_SUART_MCASP == 0)
416 #define MCASP_PSC_OFFSET (CSL_PSC_MCASP0)
417 #elif (CONFIG_OMAPL_SUART_MCASP == 1)
418 #define MCASP_PSC_OFFSET (CSL_PSC_MCASP0 + 1)
419 #elif (CONFIG_OMAPL_SUART_MCASP == 2)
420 #define MCASP_PSC_OFFSET (CSL_PSC_MCASP0 + 2)
421 #endif
422 
423 /*
424  * mcasp psc enable routine
425  */
426 void suart_mcasp_psc_enable(unsigned int psc1_addr)
427 {
428  CSL_PscRegsOvly PSC = (CSL_PscRegsOvly) psc1_addr; // CSL_PSC_1_REGS;
429 
430  // Wait for any outstanding transition to complete
431  while (CSL_FEXT(PSC->PTSTAT, PSC_PTSTAT_GOSTAT0) ==
433 
434  // If we are already in that state, just return
435  if (CSL_FEXT(PSC->MDSTAT[MCASP_PSC_OFFSET], PSC_MDSTAT_STATE) ==
437  return;
438 
439  // Perform transition
440  CSL_FINST(PSC->MDCTL[MCASP_PSC_OFFSET], PSC_MDCTL_NEXT, ENABLE);
441  CSL_FINST(PSC->PTCMD, PSC_PTCMD_GO0, SET);
442 
443  // Wait for transition to complete
444  while (CSL_FEXT(PSC->PTSTAT, PSC_PTSTAT_GOSTAT0) ==
446 
447  // Wait and verify the state
448  while (CSL_FEXT(PSC->MDSTAT[MCASP_PSC_OFFSET], PSC_MDSTAT_STATE) !=
450 }
451 
452 /*
453  * mcasp psc disable routine
454  */
455 void suart_mcasp_psc_disable(unsigned int psc1_addr)
456 {
457  CSL_PscRegsOvly PSC = (CSL_PscRegsOvly) psc1_addr; // CSL_PSC_1_REGS;
458 
459  // Wait for any outstanding transition to complete
460  while (CSL_FEXT(PSC->PTSTAT, PSC_PTSTAT_GOSTAT0) ==
462 
463  // If we are already in that state, just return
464  if (CSL_FEXT(PSC->MDSTAT[MCASP_PSC_OFFSET], PSC_MDSTAT_STATE) ==
466  return;
467 
468  // Perform transition
469  CSL_FINST(PSC->MDCTL[MCASP_PSC_OFFSET], PSC_MDCTL_NEXT, SYNCRST);
470  CSL_FINST(PSC->PTCMD, PSC_PTCMD_GO0, SET);
471 
472  // Wait for transition to complete
473  while (CSL_FEXT(PSC->PTSTAT, PSC_PTSTAT_GOSTAT0) ==
475 
476  // Wait and verify the state
477  while (CSL_FEXT(PSC->MDSTAT[MCASP_PSC_OFFSET], PSC_MDSTAT_STATE) !=
479 }
480 /* End of file */
#define SUART_INVALID_OVERSAMPLING
Definition: suart_err.h:64
#define PRU_SUART3_CONFIG_TX_SER
void suart_mcasp_psc_enable(unsigned int psc1_addr)
Definition: suart_utils.c:426
#define PRU_SUART6_CONFIG_TX_SER
#define CSL_FEXT(reg, PER_REG_FIELD)
Definition: c_i2c.c:95
#define SUART_16X_OVRSMPL
Definition: suart_api.h:81
#define SUART_INVALID_RX_BAUD
Definition: suart_err.h:65
#define SUART_SUCCESS
Definition: suart_api.h:51
void * mcasp_io_addr
Definition: pru.h:112
#define SUART_8X_OVRSMPL
Definition: suart_api.h:80
#define CSL_PSC_MDSTAT_STATE_SYNCRST
void suart_mcasp_config(unsigned int mcasp_addr, unsigned int txBaudValue, unsigned int rxBaudValue, unsigned int oversampling, arm_pru_iomap *pru_arm_iomap)
Definition: suart_utils.c:154
volatile CSL_McaspRegs * CSL_McaspRegsOvly
Definition: cslr_mcasp.h:189
#define CSL_MCASP_PFUNC_RESETVAL
Definition: cslr_mcasp.h:359
#define CSL_PSC_PTSTAT_GOSTAT0_IN_TRANSITION
unsigned int lt_rx_16x_baud_rate[][SUART_TRX_DIV_CONF_SZ]
Definition: suart_utils.c:114
short suart_asp_baud_set(unsigned int txBaudValue, unsigned int rxBaudValue, unsigned int oversampling, arm_pru_iomap *pru_arm_iomap)
Definition: suart_utils.c:374
#define SUART_FALSE
Definition: suart_api.h:54
#define SUART_NUM_OF_BAUDS_SUPPORTED
Definition: suart_utils.h:69
short suart_asp_serializer_deactivate(unsigned short u16srNum, arm_pru_iomap *pru_arm_iomap)
Definition: suart_utils.c:392
#define PRU_SUART2_CONFIG_TX_SER
volatile CSL_PscRegs * CSL_PscRegsOvly
#define MCASP_PDIR_VAL
Definition: suart_utils.h:71
#define PRU_SUART1_CONFIG_TX_SER
#define CSL_MCASP_ACLKXCTL_CLKXDIV_SHIFT
Definition: cslr_mcasp.h:2485
unsigned int lt_tx_baud_rate[][SUART_TRX_DIV_CONF_SZ]
Definition: suart_utils.c:56
#define CSL_MCASP_AHCLKXCTL_HCLKXDIV_SHIFT
Definition: cslr_mcasp.h:2507
void suart_mcasp_tx_serialzier_set(unsigned int serializerNum, arm_pru_iomap *pru_arm_iomap)
Definition: suart_utils.c:252
#define SUART_TRX_DIV_CONF_SZ
Definition: suart_utils.c:35
#define PRU_SUART4_CONFIG_TX_SER
#define CSL_FINST(reg, PER_REG_FIELD, TOKEN)
#define PRU_SUART8_CONFIG_TX_SER
void suart_mcasp_psc_disable(unsigned int psc1_addr)
Definition: suart_utils.c:455
#define PRU_SUART5_CONFIG_TX_SER
#define PRU_SUART7_CONFIG_TX_SER
#define MCASP_PSC_OFFSET
Definition: suart_utils.c:416
void suart_mcasp_reset(arm_pru_iomap *pru_arm_iomap)
Definition: suart_utils.c:140
#define SUART_TRUE
Definition: suart_api.h:55
#define CSL_PSC_MDSTAT_STATE_ENABLE
#define SUART_INVALID_TX_BAUD
Definition: suart_err.h:63
unsigned int lt_rx_8x_baud_rate[][SUART_TRX_DIV_CONF_SZ]
Definition: suart_utils.c:85
#define SUART_INVALID_SR_NUM
Definition: suart_err.h:71
#define NULL