source: svn/newcon3bcm2_21bu/magnum/portinginterface/spi/7552/bspi.c @ 66

Last change on this file since 66 was 66, checked in by megakiss, 11 years ago

키패드 기능 연결

전원키 누르고 리모콘 누르면 학습
CH+ 간격 1초 증가 MAX:15
CH- 간격 1초 감소 MIN :1

  • Property svn:executable set to *
File size: 39.5 KB
Line 
1
2/***************************************************************************
3 *     Copyright (c) 2003-2011, Broadcom Corporation
4 *     All Rights Reserved
5 *     Confidential Property of Broadcom Corporation
6 *
7 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
8 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
9 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
10 *
11 * $brcm_Workfile: bspi.c $
12 * $brcm_Revision: Hydra_Software_Devel/66 $
13 * $brcm_Date: 11/21/11 6:20p $
14 *
15 * Module Description:
16 *
17 * Revision History:
18 *
19 * $brcm_Log: /magnum/portinginterface/spi/7435/bspi.c $
20 *
21 * Hydra_Software_Devel/66   11/21/11 6:20p mward
22 * SW7435-7: Add 7435.
23 *
24 * Hydra_Software_Devel/65   10/11/11 2:03p agin
25 * SW7429-14:  Added support for 7429.
26 *
27 * Hydra_Software_Devel/64   9/13/11 5:20p enavarro
28 * SWSATFE-86: added BCM4528 support
29 *
30 * Hydra_Software_Devel/63   5/5/11 3:58p agin
31 * SW7346-170:  Use MAX_SPI_CHANNELS from bspi.h.
32 *
33 * Hydra_Software_Devel/62   5/2/11 2:36p agin
34 * SW7346-170:  Change MAX_SPI_CHANNELS for 7346 to 3.
35 *
36 * Hydra_Software_Devel/61   3/21/11 7:17a enavarro
37 * SWSATFE-97: add support for 4550
38 *
39 * Hydra_Software_Devel/60   12/27/10 2:50p xhuang
40 * SW7358-29: Add 7358/7552 support
41 *
42 * Hydra_Software_Devel/59   12/8/10 6:05p katrep
43 * SW7231-4:add support for 7231
44 *
45 * Hydra_Software_Devel/58   12/7/10 6:18p jrubio
46 * SW7344-9: add 7344/7346 support
47 *
48 * Hydra_Software_Devel/57   11/2/10 5:22p hongtaoz
49 * SW7425-9: added 7425 support;
50 *
51 * Hydra_Software_Devel/56   10/7/10 4:48p nickh
52 * SW7422-74: Add 7422 support
53 *
54 * Hydra_Software_Devel/55   5/7/10 6:42p jkim
55 * CR3548-909: implement get function for SetDTLConfig() and Set
56 * RDSCLKConfig()
57 *
58 * Hydra_Software_Devel/54   4/23/10 2:29p erickson
59 * SW3548-2904: don't write directly to BCHP_IRQ0_SPI_IRQEN because of
60 * possible linux SPI flash collision, clean up BCHP_CHIP lists, add _isr
61 * to two priv functions
62 *
63 * Hydra_Software_Devel/53   12/13/09 6:44p rpereira
64 * SW7550-41: Fixed compilation issues for 7550
65 *
66 * Hydra_Software_Devel/52   9/15/09 10:46a rpereira
67 * SW7630-45: Adding 7630 support
68 *
69 * Hydra_Software_Devel/51   9/1/09 9:10p rpereira
70 * SW7550-30: Adding 7550 support
71 *
72 * Hydra_Software_Devel/50   8/20/09 4:28p mward
73 * PR55545: Support 7125.
74 *
75 * Hydra_Software_Devel/49   8/17/09 3:46p mward
76 * PR55232: Typo'd '7400' to '7401'.
77 *
78 * Hydra_Software_Devel/48   8/10/09 5:25p jrubio
79 * PR55232: add 7340/7342 support
80 *
81 * Hydra_Software_Devel/47   4/9/09 5:26p rpereira
82 * PR52971: added 7635 support
83 *
84 * Hydra_Software_Devel/46   3/9/09 4:49p jkim
85 * PR50132: remove the dead code
86 *
87 * Hydra_Software_Devel/45   1/31/09 1:31a jrubio
88 * PR51629: add 7336 support
89 *
90 * Hydra_Software_Devel/44   12/5/08 10:47a farshidf
91 * PR47734: add the hChnDev->chnNo  initiialization in BSPI_OpenChannel
92 *
93 * Hydra_Software_Devel/43   12/3/08 10:22a kaushikb
94 * PR49867: Adding support for 7420
95 *
96 * Hydra_Software_Devel/42   10/22/08 2:28p farshidf
97 * PR47943: add the default settings for channel 2
98 *
99 * Hydra_Software_Devel/41   10/16/08 2:52p farshidf
100 * PR47943: Extend magnum SPI PI to allow control of BSPI pins via MSPI
101 * core
102 *
103 * Hydra_Software_Devel/40   10/13/08 3:35p jkim
104 * PR46713: modify function prototype per magnum coding guideline
105 *
106 * Hydra_Software_Devel/39   8/21/08 9:14a fbasso
107 * PR 44544: added support for 7601
108 *
109 * Hydra_Software_Devel/38   6/26/08 11:04a farshidf
110 * PR44170:add BKNI_CriticalSection around a register write
111 *
112 * Hydra_Software_Devel/37   6/23/08 3:53p farshidf
113 * PR43831: add 3549/3556 flags around the new code
114 *
115 * Hydra_Software_Devel/36   6/23/08 3:27p farshidf
116 * PR43831: PR43831: remove the space the include name
117 * PR43831: move the Master enable/disable  bit to open and close spi
118 * PR43831: change the register read/write to BREG
119 * PR43831: fix the SPI interface for 3549/3556 by adding new bit settings
120 *
121 * Hydra_Software_Devel/PR43831/4   6/23/08 3:25p farshidf
122 * PR43831: remove the space the include name
123 *
124 * Hydra_Software_Devel/PR43831/3   6/23/08 3:19p farshidf
125 * PR43831: move the Master enable/disable  bit to open and close spi
126 *
127 * Hydra_Software_Devel/PR43831/2   6/23/08 10:04a farshidf
128 * PR43831: change the register read/write to BREG
129 *
130 * Hydra_Software_Devel/PR43831/1   6/20/08 5:18p farshidf
131 * PR43831: fix the SPI interface for 3549/3556 by adding new bit settings
132 *
133 * Hydra_Software_Devel/35   4/4/08 2:44p farshidf
134 * PR39199: Add support for 3548/3556
135 *
136 * Hydra_Software_Devel/34   11/28/07 11:55a farshidf
137 * PR36894: add 7335 support
138 *
139 * Hydra_Software_Devel/33   10/31/07 2:20p jkim
140 * PR14344: Add support for 7325
141 *
142 * Hydra_Software_Devel/33   10/25/07 11:27a jkim
143 * PR14344: Add support for 7325
144 *
145 * Hydra_Software_Devel/33   10/14/07 3:54p jkim
146 * PR14344: add 7325 support
147 *
148 * Hydra_Software_Devel/32   5/21/07 4:09p jkim
149 * PR30844: Add 7405 support
150 *
151 * Hydra_Software_Devel/31   5/17/07 10:28a jkim
152 * PR14344: modified to support slower devices. DTL and RDSCLK are now
153 * settable.
154 *
155 * Hydra_Software_Devel/30   2/16/07 11:34a jkim
156 * PR14344: Added 7440 support
157 *
158 * Hydra_Software_Devel/29   2/2/07 11:21a jkim
159 * PR27238: Modify to use the correct IRQ definition
160 *
161 * Hydra_Software_Devel/28   1/12/07 4:19p jkim
162 * PR14344: Add 3563 support
163 *
164 * Hydra_Software_Devel/27   11/9/06 11:36a jkim
165 * PR14344: added 7403 support
166 *
167 * Hydra_Software_Devel/26   9/19/06 5:20p agin
168 * PR24339: Resolve compiler warning for DEBUG=n builds for UPG modules.
169 *
170 * Hydra_Software_Devel/25   8/9/06 11:08a agin
171 * PR23362: Add 3563 support.
172 *
173 * Hydra_Software_Devel/25   8/9/06 11:08a agin
174 * PR23362: Add 3563 support.
175 *
176 * Hydra_Software_Devel/24   6/15/06 5:13p mward
177 * PR21684: Add support for 7118 chip 97118 board
178 *
179 * Hydra_Software_Devel/23   3/21/06 3:04p jkim
180 * PR20326: Add support for 7438
181 *
182 * Hydra_Software_Devel/22   1/14/06 11:36p agin
183 * PR19076: Support BCM7400.
184 *
185 * Hydra_Software_Devel/21   8/23/05 5:08p jkim
186 * PR14344: Adding 7401 support
187 *
188 * Hydra_Software_Devel/20   5/9/05 11:41a dlwin
189 * PR 14698: Resolve "unused ..." warnings.
190 *
191 * Hydra_Software_Devel/19   3/18/05 6:50p agin
192 * PR14520: keypad for 97398
193 *
194 * Hydra_Software_Devel/18   3/17/05 5:38p dlwin
195 * PR 14240: Added support for 3560.
196 *
197 * Hydra_Software_Devel/17   3/10/05 9:37a dlwin
198 * PR 14240: Added support for 3560
199 *
200 * Hydra_Software_Devel/16   7/12/04 2:15p brianlee
201 * PR11723: Get rid of floating point calculation.
202 *
203 * Hydra_Software_Devel/15   3/26/04 4:32p brianlee
204 * PR8971: Remove BDBG_ASSERT() for malloc failure.
205 *
206 * Hydra_Software_Devel/14   2/9/04 6:42p brianlee
207 * PR242: Added support for 16-bit transfer mode.
208 *
209 * Hydra_Software_Devel/13   1/28/04 10:22a brianlee
210 * PR9499: Fixed breg_spi.h file inclusion.
211 *
212 * Hydra_Software_Devel/12   1/22/04 10:20a brianlee
213 * PR242: In BSPI_CloseChannel(), test to see if the callback is NULL
214 * before destroying it.
215 *
216 * Hydra_Software_Devel/11   1/13/04 5:02p brianlee
217 * PR9268: Make write structures constant.
218 *
219 * Hydra_Software_Devel/10   12/29/03 3:59p marcusk
220 * PR9117: Updated with changes required to support interrupt ids rather
221 * than strings.
222 *
223 * Hydra_Software_Devel/9   12/5/03 2:45p brianlee
224 * PR8865: Check for maximum SPI transfer size of 16.
225 *
226 * Hydra_Software_Devel/8   11/6/03 9:51a brianlee
227 * Added the function BSPI_CloseSpiRegHandle().
228 *
229 * Hydra_Software_Devel/7   11/4/03 6:56p brianlee
230 * Fixed a compilation error.
231 *
232 * Hydra_Software_Devel/6   11/4/03 6:54p brianlee
233 * Get rid of enter/leave macros.
234 *
235 * Hydra_Software_Devel/5   10/15/03 2:53p brianlee
236 * Fixed problem with SPI read and write.
237 *
238 * Hydra_Software_Devel/4   9/24/03 2:10p brianlee
239 * Changed the names of header files.
240 *
241 * Hydra_Software_Devel/3   9/19/03 1:53p brianlee
242 * Fixed warnings from Midas build.
243 *
244 * Hydra_Software_Devel/2   9/15/03 10:26a brianlee
245 * Changed TRUE/FALSE to lower case.
246 *
247 * Hydra_Software_Devel/1   9/11/03 6:25p brianlee
248 * Initial version.
249 *
250 ***************************************************************************/
251#include "bstd.h"
252#include "breg_spi_priv.h"
253#include "bspi.h"
254#include "bspi_priv.h"
255#include "bchp_mspi.h"
256#if (BCHP_CHIP!=4550) && (BCHP_CHIP!=4528)
257#include "bchp_irq0.h"
258#endif
259#include "bchp_int_id_irq0.h"
260#if (BCHP_CHIP==3548) || (BCHP_CHIP==3556) || (BCHP_CHIP==4550) || (BCHP_CHIP==4528)
261#include "bchp_bspi.h"
262#endif
263#if (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7429) || (BCHP_CHIP==7344) || \
264        (BCHP_CHIP==7346) || (BCHP_CHIP==7231) || (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || (BCHP_CHIP==7435)
265#include "bchp_int_id_irq0_aon.h"
266#endif
267
268BDBG_MODULE(bspi);
269
270#define DEV_MAGIC_ID            ((BERR_SPI_ID<<16) | 0xFACE)
271
272#define BSPI_CHK_RETCODE( rc, func )        \
273do {                                        \
274    if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
275    {                                       \
276        goto done;                          \
277    }                                       \
278} while(0)
279
280#define MAX_SPI_XFER        16          /* maximum number of transfers allowed per transaction */
281
282#define SPI_SYSTEM_CLK      27000000    /* 27 MHz */
283#define MAX_SPI_BAUD        1687500     /* SPBR = 8, 27MHZ */
284#define MIN_SPI_BAUD        52734       /* SPBR = 0, 27MHZ */
285
286/* Format of the CDRAM, for some reason, this does not show up in RDB file */
287#define SPI_CDRAM_CONT              0x80
288#define SPI_CDRAM_BITSE             0x40
289#define SPI_CDRAM_DT                0x20
290#define SPI_CDRAM_DSCK              0x10
291#define SPI_CDRAM_PCS_MASK          0x07
292
293#define SPI_CDRAM_PCS_PCS0          0x01
294#define SPI_CDRAM_PCS_PCS1          0x02
295#if MAX_SPI_CHANNELS > 2
296#define SPI_CDRAM_PCS_PCS2          0x04
297#else
298#define SPI_CDRAM_PCS_PCS2          0x00
299#endif
300
301#define SPI_CDRAM_PCS_DISABLE_ALL   (SPI_CDRAM_PCS_PCS0 | SPI_CDRAM_PCS_PCS1 | SPI_CDRAM_PCS_PCS2)
302
303#define SPI_POLLING_INTERVAL        10      /* in usecs */
304
305static void BSPI_P_EnableInt_isr( BSPI_Handle hDev );
306static void BSPI_P_DisableInt_isr( BSPI_Handle hDev );
307
308/*******************************************************************************
309*
310*   Private Module Handles
311*
312*******************************************************************************/
313
314typedef struct BSPI_P_Handle
315{
316    uint32_t        magicId;                    /* Used to check if structure is corrupt */
317    BCHP_Handle     hChip;
318    BREG_Handle     hRegister;
319    BINT_Handle     hInterrupt;
320    unsigned int    maxChnNo;
321    BSPI_ChannelHandle hSpiChn[MAX_SPI_CHANNELS];
322} BSPI_P_Handle;
323
324typedef struct BSPI_P_ChannelHandle
325{
326    uint32_t            magicId;                    /* Used to check if structure is corrupt */
327    BSPI_Handle         hSpi;
328    unsigned int        chnNo;
329    BKNI_EventHandle    hChnEvent;
330    BINT_CallbackHandle hChnCallback;
331    BSPI_Pcs            pcs;
332    uint32_t            baud;
333    uint8_t             clkConfig;
334    bool                intMode;
335    uint8_t             bitsPerTxfr;
336    bool                lastByteContinueEnable;     /* Last Byte Contiue Enable Flag */
337    bool                useUserDtlAndDsclk;         /* Use User specified DTL and DSCLK */
338} BSPI_P_ChannelHandle;
339
340
341
342/*******************************************************************************
343*
344*   Default Module Settings
345*
346*******************************************************************************/
347static const BSPI_Settings defSpiSettings = NULL;
348
349static const BSPI_ChannelSettings defSpiChn0Settings =
350{
351    MAX_SPI_BAUD,
352    BCHP_MSPI_SPCR0_MSB_CPOL_MASK | BCHP_MSPI_SPCR0_MSB_CPHA_MASK,
353    true,
354    8,
355    false,
356    false
357};
358
359static const BSPI_ChannelSettings defSpiChn1Settings =
360{
361    MAX_SPI_BAUD,
362    BCHP_MSPI_SPCR0_MSB_CPOL_MASK | BCHP_MSPI_SPCR0_MSB_CPHA_MASK,
363    true,
364    8,
365    false,
366    false
367};
368
369#if MAX_SPI_CHANNELS > 2
370static const BSPI_ChannelSettings defSpiChn2Settings =
371{
372    MAX_SPI_BAUD,
373    BCHP_MSPI_SPCR0_MSB_CPOL_MASK | BCHP_MSPI_SPCR0_MSB_CPHA_MASK,
374    true,
375    8,
376    false,
377    false
378};
379#endif
380
381#if (BCHP_CHIP==3548) || (BCHP_CHIP==3556)
382#define BSPI_USE_MAST_N_BOOT 1
383#endif
384
385/*******************************************************************************
386*
387*   Public Module Functions
388*
389*******************************************************************************/
390BERR_Code BSPI_Open(
391    BSPI_Handle *pSpi,                  /* [output] Returns handle */
392    BCHP_Handle hChip,                  /* Chip handle */
393    BREG_Handle hRegister,              /* Register handle */
394    BINT_Handle hInterrupt,             /* Interrupt handle */
395    const BSPI_Settings *pDefSettings   /* Default settings */
396    )
397{
398    BERR_Code retCode = BERR_SUCCESS;
399    BSPI_Handle hDev;
400    unsigned int chnIdx;
401#if BSPI_USE_MAST_N_BOOT
402    uint32_t            lval = 0;
403#endif
404
405
406    /* Sanity check on the handles we've been given. */
407    BDBG_ASSERT( hChip );
408    BDBG_ASSERT( hRegister );
409    BDBG_ASSERT( hInterrupt );
410    BSTD_UNUSED( pDefSettings );
411
412    /* Alloc memory from the system heap */
413    hDev = (BSPI_Handle) BKNI_Malloc( sizeof( BSPI_P_Handle ) );
414    if( hDev == NULL )
415    {
416        *pSpi = NULL;
417        retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
418        BDBG_ERR(("BSPI_Open: BKNI_malloc() failed\n"));
419        goto done;
420    }
421
422    hDev->magicId   = DEV_MAGIC_ID;
423    hDev->hChip     = hChip;
424    hDev->hRegister = hRegister;
425    hDev->hInterrupt = hInterrupt;
426    hDev->maxChnNo  = MAX_SPI_CHANNELS;
427    for( chnIdx = 0; chnIdx < hDev->maxChnNo; chnIdx++ )
428    {
429        hDev->hSpiChn[chnIdx] = NULL;
430    }
431    *pSpi = hDev;
432
433    /* new bit added in 3548/3556 to enable the pin */
434#if BSPI_USE_MAST_N_BOOT
435    lval = BREG_Read32(hDev->hRegister, BCHP_BSPI_MAST_N_BOOT_CTRL);
436    lval |= BCHP_BSPI_MAST_N_BOOT_CTRL_mast_n_boot_MASK;
437    BREG_Write32( hDev->hRegister, BCHP_BSPI_MAST_N_BOOT_CTRL, lval );
438#endif
439
440done:
441    return( retCode );
442}
443
444BERR_Code BSPI_Close(
445    BSPI_Handle hDev                    /* Device handle */
446    )
447{
448    BERR_Code retCode = BERR_SUCCESS;
449#if BSPI_USE_MAST_N_BOOT
450    uint32_t            lval = 0;
451
452    /* new bit added in 3548/3556 to enable the pin */
453    lval = BREG_Read32(hDev->hRegister, BCHP_BSPI_MAST_N_BOOT_CTRL);
454    lval &= ~BCHP_BSPI_MAST_N_BOOT_CTRL_mast_n_boot_MASK;
455    BREG_Write32( hDev->hRegister, BCHP_BSPI_MAST_N_BOOT_CTRL, lval );
456#endif
457
458    BDBG_ASSERT( hDev );
459    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
460
461    BKNI_Free( (void *) hDev );
462
463    return( retCode );
464}
465
466BERR_Code BSPI_GetDefaultSettings(
467    BSPI_Settings *pDefSettings,        /* [output] Returns default setting */
468    BCHP_Handle hChip                   /* Chip handle */
469    )
470{
471    BERR_Code retCode = BERR_SUCCESS;
472
473    BSTD_UNUSED(hChip);
474
475    *pDefSettings = defSpiSettings;
476
477    return( retCode );
478}
479
480BERR_Code BSPI_GetTotalChannels(
481    BSPI_Handle hDev,                   /* Device handle */
482    unsigned int *totalChannels         /* [output] Returns total number downstream channels supported */
483    )
484{
485    BERR_Code retCode = BERR_SUCCESS;
486
487
488    BDBG_ASSERT( hDev );
489    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
490
491    *totalChannels = hDev->maxChnNo;
492
493    return( retCode );
494}
495
496BERR_Code BSPI_GetChannelDefaultSettings(
497    BSPI_Handle hDev,                   /* Device handle */
498    unsigned int channelNo,             /* Channel number to default setting for */
499    BSPI_ChannelSettings *pChnDefSettings /* [output] Returns channel default setting */
500    )
501{
502    BERR_Code retCode = BERR_SUCCESS;
503
504#if !BDBG_DEBUG_BUILD
505    BSTD_UNUSED(hDev);
506#endif
507
508    BDBG_ASSERT( hDev );
509    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
510
511    switch (channelNo)
512    {
513        case 0:
514            *pChnDefSettings = defSpiChn0Settings;
515            break;
516
517        case 1:
518            *pChnDefSettings = defSpiChn1Settings;
519            break;
520#if MAX_SPI_CHANNELS > 2
521        case 2:
522            *pChnDefSettings = defSpiChn2Settings;
523            break;
524#endif
525        default:
526            retCode = BERR_TRACE(BERR_INVALID_PARAMETER);
527            break;
528
529    }
530
531    return( retCode );
532}
533
534BERR_Code BSPI_OpenChannel(
535    BSPI_Handle hDev,                   /* Device handle */
536    BSPI_ChannelHandle *phChn,          /* [output] Returns channel handle */
537    unsigned int channelNo,             /* Channel number to open */
538    const BSPI_ChannelSettings *pChnDefSettings /* Channel default setting */
539    )
540{
541    BERR_Code           retCode = BERR_SUCCESS;
542    BSPI_ChannelHandle  hChnDev;
543
544    BDBG_ASSERT( hDev );
545    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
546
547    hChnDev = NULL;
548    if( channelNo < hDev->maxChnNo )
549    {
550        if( hDev->hSpiChn[channelNo] == NULL )
551        {
552            if ((pChnDefSettings->bitsPerTxfr != 8) && (pChnDefSettings->bitsPerTxfr != 16))
553            {
554                retCode = BERR_INVALID_PARAMETER;
555                goto done;
556            }
557            /* Alloc memory from the system heap */
558            hChnDev = (BSPI_ChannelHandle) BKNI_Malloc( sizeof( BSPI_P_ChannelHandle ) );
559            if( hChnDev == NULL )
560            {
561                *phChn = NULL;
562                retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
563                BDBG_ERR(("BSPI_OpenChannel: BKNI_malloc() failed\n"));
564                goto done;
565            }
566
567            BSPI_CHK_RETCODE( retCode, BKNI_CreateEvent( &(hChnDev->hChnEvent) ) );
568            hChnDev->magicId    = DEV_MAGIC_ID;
569            hChnDev->hSpi       = hDev;
570            switch (channelNo)
571            {
572                case 0:
573                    hChnDev->pcs = BSPI_Pcs_eUpgSpiPcs0;
574                    break;
575                case 1:
576                    hChnDev->pcs = BSPI_Pcs_eUpgSpiPcs1;
577                    break;
578            #if MAX_SPI_CHANNELS > 2
579                case 2:
580                    hChnDev->pcs = BSPI_Pcs_eUpgSpiPcs2;
581                    break;
582            #endif
583                default:
584                    retCode = BERR_TRACE(BERR_INVALID_PARAMETER);
585                    goto done;
586            }
587            hChnDev->baud       = pChnDefSettings->baud;
588            hChnDev->clkConfig  = pChnDefSettings->clkConfig;
589            hChnDev->bitsPerTxfr = pChnDefSettings->bitsPerTxfr;
590            hChnDev->lastByteContinueEnable = pChnDefSettings->lastByteContinueEnable;
591            hChnDev->useUserDtlAndDsclk = pChnDefSettings->useUserDtlAndDsclk;
592            hChnDev->chnNo = channelNo;
593            hDev->hSpiChn[channelNo] = hChnDev;
594
595            /* Program SPI clock setting */
596            BSPI_P_SetClk (hChnDev, pChnDefSettings->baud, pChnDefSettings->clkConfig);
597
598            /*
599             * Enable interrupt for this channel
600             */
601            hChnDev->intMode = pChnDefSettings->intMode;
602            if (hChnDev->intMode == true)
603            {
604                /*
605                 * Register and enable L2 interrupt.
606                 */
607#if !defined(BCHP_INT_ID_spi_irqen)
608#define BCHP_INT_ID_spi_irqen           BCHP_INT_ID_spi
609#endif
610                retCode = BINT_CreateCallback(&(hChnDev->hChnCallback), hDev->hInterrupt, BCHP_INT_ID_spi_irqen, BSPI_P_HandleInterrupt_Isr, (void *) hChnDev, 0x00);
611                if (retCode) {
612                    BDBG_ERR(("Unable to enable IRQ0_SPI_IRQEN. See bint.inc and the BCHP_DISABLE_IRQ0_SPI option."));
613                    retCode = BERR_TRACE(retCode);
614                    goto done;
615                }
616
617                retCode = BINT_EnableCallback(hChnDev->hChnCallback);
618                if (retCode) {
619                    retCode = BERR_TRACE(retCode);
620                    goto done;
621                }
622
623                BKNI_EnterCriticalSection();
624                BSPI_P_EnableInt_isr(hDev);
625                BKNI_LeaveCriticalSection();
626            }
627            else
628            {
629                hChnDev->hChnCallback = NULL;
630                /* No need to disable BCHP_IRQ0_SPI_IRQEN. No one should have enabled it. Be aware that direct access to BCHP_IRQ0_SPI_IRQEN is not allowed
631                in this PI. A potential conflict with the kernel is possible. See bint.inc for a note. */
632
633                BKNI_EnterCriticalSection();
634                BSPI_P_DisableInt_isr(hDev);
635                BKNI_LeaveCriticalSection();
636            }
637
638            *phChn = hChnDev;
639        }
640        else
641        {
642            retCode = BSPI_ERR_NOTAVAIL_CHN_NO;
643        }
644    }
645    else
646    {
647        retCode = BERR_INVALID_PARAMETER;
648    }
649
650done:
651
652    if( retCode != BERR_SUCCESS )
653    {
654        if( hChnDev != NULL )
655        {
656            BKNI_DestroyEvent( hChnDev->hChnEvent );
657            BKNI_Free( hChnDev );
658            hDev->hSpiChn[channelNo] = NULL;
659            *phChn = NULL;
660        }
661    }
662    return( retCode );
663}
664
665BERR_Code BSPI_CloseChannel(
666    BSPI_ChannelHandle hChn         /* Device channel handle */
667    )
668{
669    BERR_Code retCode = BERR_SUCCESS;
670    BSPI_Handle hDev;
671    unsigned int chnNo;
672
673    BDBG_ASSERT( hChn );
674    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
675
676    hDev = hChn->hSpi;
677    /*
678     * Disable interrupt for this channel
679     */
680    BKNI_EnterCriticalSection();
681    BSPI_P_DisableInt_isr(hDev);
682    BKNI_LeaveCriticalSection();
683
684    if (hChn->hChnCallback != NULL)
685    {
686        (void)BINT_DestroyCallback( hChn->hChnCallback );
687    }
688    BKNI_DestroyEvent( hChn->hChnEvent );
689    chnNo = hChn->chnNo;
690    BKNI_Free( hChn );
691    hDev->hSpiChn[chnNo] = NULL;
692
693    return( retCode );
694}
695
696BERR_Code BSPI_GetDevice(
697    BSPI_ChannelHandle hChn,            /* Device channel handle */
698    BSPI_Handle *phDev                  /* [output] Returns Device handle */
699    )
700{
701    BERR_Code retCode = BERR_SUCCESS;
702
703
704    BDBG_ASSERT( hChn );
705    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
706
707    *phDev = hChn->hSpi;
708
709    return( retCode );
710}
711
712
713BERR_Code BSPI_CreateSpiRegHandle(
714    BSPI_ChannelHandle hChn,            /* Device channel handle */
715    BREG_SPI_Handle *pSpiReg            /* [output]  */
716    )
717{
718    BERR_Code retCode = BERR_SUCCESS;
719
720
721    BDBG_ASSERT( hChn );
722    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
723
724
725    *pSpiReg = (BREG_SPI_Handle)BKNI_Malloc( sizeof(BREG_SPI_Impl) );
726    if( *pSpiReg == NULL )
727    {
728        retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
729        BDBG_ERR(("BSPI_CreateSpiRegHandle: BKNI_malloc() failed\n"));
730        goto done;
731    }
732
733    (*pSpiReg)->context                     = (void *)hChn;
734    (*pSpiReg)->BREG_SPI_Write_Func         = BSPI_P_Write;
735    (*pSpiReg)->BREG_SPI_Read_Func          = BSPI_P_Read;
736
737done:
738    return( retCode );
739}
740
741BERR_Code BSPI_CloseSpiRegHandle(
742    BREG_SPI_Handle     hSpiReg         /* SPI register handle */
743    )
744{
745
746    BDBG_ASSERT( hSpiReg );
747    BKNI_Free( (void *) hSpiReg );
748
749    return BERR_SUCCESS ;
750}
751
752BERR_Code BSPI_AbortTxfr(
753    BSPI_ChannelHandle hChn         /* Device channel handle */
754    )
755{
756    BERR_Code retCode = BERR_SUCCESS;
757    uint32_t lval;
758    BSPI_Handle hDev;
759
760    BDBG_ASSERT( hChn );
761    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
762
763    hDev = hChn->hSpi;
764    lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_SPCR2);
765    if (!(lval & BCHP_MSPI_SPCR2_spe_MASK))         /* if no transfer is going on, we're done */
766        goto done;
767
768    /* Set the HALT bit to stop the transfer */
769    lval |= BCHP_MSPI_SPCR2_halt_MASK;
770    BREG_Write32 (hDev->hRegister, BCHP_MSPI_SPCR2, lval);
771
772    /* Now wait until the Halt Acknowledge bit is set */
773    do
774    {
775        lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_MSPI_STATUS);
776    } while (!(lval & BCHP_MSPI_MSPI_STATUS_HALTA_MASK));
777
778    BKNI_EnterCriticalSection();
779    BREG_Write32( hDev->hRegister, BCHP_MSPI_MSPI_STATUS, 0);
780    BKNI_LeaveCriticalSection();
781    BREG_Write32 (hDev->hRegister, BCHP_MSPI_SPCR2, 0);
782
783done:
784    return( retCode );
785}
786
787BERR_Code BSPI_GetClkConfig(
788    BSPI_ChannelHandle hChn,                /* Device channel handle */
789    uint8_t *pClkConfig                     /* Pointer to clock config */
790    )
791{
792    BERR_Code retCode = BERR_SUCCESS;
793
794    BDBG_ASSERT( hChn );
795    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
796
797    *pClkConfig = hChn->clkConfig;
798
799    return( retCode );
800}
801
802BERR_Code BSPI_SetClkConfig(
803    BSPI_ChannelHandle hChn,            /* Device channel handle */
804    uint8_t clkConfig                   /* clock config */
805    )
806{
807    BERR_Code retCode = BERR_SUCCESS;
808
809    BDBG_ASSERT( hChn );
810    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
811
812    hChn->clkConfig = clkConfig;
813
814    return( retCode );
815}
816
817BERR_Code BSPI_GetDTLConfig (
818    BSPI_ChannelHandle hChn,    /* Device channel handle */
819    uint32_t *pDTLConfig        /* pointer to DTLConfig */
820    )
821{
822    BSPI_Handle         hDev;
823    uint32_t            data;
824    BERR_Code           retCode = BERR_SUCCESS;
825
826    BDBG_ASSERT( hChn );
827    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
828
829    hDev = hChn->hSpi;
830    data = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR1_LSB);
831    *pDTLConfig = (data & BCHP_MSPI_SPCR1_LSB_DTL_MASK);
832
833    return( retCode );
834}
835
836BERR_Code BSPI_SetDTLConfig (
837    BSPI_ChannelHandle context,             /* Device channel handle */
838    const uint32_t data         /* data to write */
839    )
840{
841    BSPI_Handle         hDev;
842    BSPI_ChannelHandle  hChn;
843    BERR_Code           retCode = BERR_SUCCESS;
844
845    if (data > 255)
846    {
847        retCode = BERR_INVALID_PARAMETER;
848        goto done;
849    }
850
851    hChn = context;
852    BDBG_ASSERT( hChn );
853    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
854
855    hDev = hChn->hSpi;
856    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR1_LSB, data );
857
858done:
859
860    return retCode;
861}
862
863
864BERR_Code BSPI_GetRDSCLKConfig (
865    BSPI_ChannelHandle hChn,    /* Device channel handle */
866    uint32_t *pRDSCLKConfig     /* pointer to RDSCLKConfig */
867    )
868{
869    BSPI_Handle         hDev;
870    uint32_t            data;
871    BERR_Code           retCode = BERR_SUCCESS;
872
873    BDBG_ASSERT( hChn );
874    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
875
876    hDev = hChn->hSpi;
877    data = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR1_MSB);
878    *pRDSCLKConfig = (data & BCHP_MSPI_SPCR1_MSB_RDSCLK_MASK);
879
880    return( retCode );
881}
882
883BERR_Code BSPI_SetRDSCLKConfig(
884    BSPI_ChannelHandle context,             /* Device channel handle */
885    const uint32_t data         /* data to write */
886    )
887{
888    BSPI_Handle         hDev;
889    BSPI_ChannelHandle  hChn;
890    BERR_Code           retCode = BERR_SUCCESS;
891
892    if (data > 255)
893    {
894        retCode = BERR_INVALID_PARAMETER;
895        goto done;
896    }
897
898    hChn = context;
899    BDBG_ASSERT( hChn );
900    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
901
902    hDev = hChn->hSpi;
903    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR1_MSB, data );
904
905done:
906
907    return retCode;
908}
909
910
911/*******************************************************************************
912*
913*   Private Module Functions
914*
915*******************************************************************************/
916BERR_Code BSPI_P_Read
917(
918    void *context,              /* Device channel handle */
919    const uint8_t *pWriteData,      /* pointer to write data  */
920    uint8_t *pReadData,         /* pointer to memory location to store read data  */
921    size_t length               /* number of bytes to read + number of bytes to write */
922)
923{
924    BSPI_Handle         hDev;
925    BSPI_ChannelHandle  hChn;
926    BERR_Code           retCode = BERR_SUCCESS;
927    uint32_t            lval = 0, i;
928
929    hChn = (BSPI_ChannelHandle)context;
930    BDBG_ASSERT( hChn );
931    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
932
933    if (((hChn->bitsPerTxfr == 8) && (length > MAX_SPI_XFER)) ||
934        ((hChn->bitsPerTxfr == 16) && (length > (MAX_SPI_XFER * 2))))
935    {
936        retCode = BERR_INVALID_PARAMETER;
937        goto done;
938    }
939
940    if ((hChn->bitsPerTxfr == 16) && (length & 0x01))       /* if the length is odd, round it up */
941        length++;
942
943    hDev = hChn->hSpi;
944
945    /* Initialize the SPI clock */
946    BSPI_P_SetClk (hChn, hChn->baud, hChn->clkConfig);
947
948    /* Fill the TX and CMD buffers */
949    if (hChn->bitsPerTxfr == 8)
950    {
951        /*
952         * 8-bit transfer mode
953         */
954        for (i=0; i<length; i++)
955        {
956            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 8), (uint32_t)(pWriteData[i]) );
957            if( hChn->useUserDtlAndDsclk == true)
958            {
959                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK;
960            }
961            else
962            {
963                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL;
964            }
965            lval &= ~(1 << hChn->pcs);
966            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + (i * 4), lval );
967        }
968
969        /* Skip for slower SPI device  */
970        if( hChn->lastByteContinueEnable == false)
971        {
972            /*
973             * Last one don't need to assert SS
974             */
975            if( hChn->useUserDtlAndDsclk == true)
976            {
977                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK;
978            }
979            else
980            {
981                lval = SPI_CDRAM_PCS_DISABLE_ALL;
982            }
983            lval &= ~(1 << hChn->pcs);
984            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + ((length - 1) * 4), lval );
985        }
986
987        /* Set queue pointers */
988        BREG_Write32( hDev->hRegister, BCHP_MSPI_NEWQP, 0 );
989        BREG_Write32( hDev->hRegister, BCHP_MSPI_ENDQP, (uint32_t)(length - 1) );
990    }
991    else
992    {
993        /*
994         * 16-bit transfer mode
995         */
996        lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR0_MSB);
997        lval &= ~BCHP_MSPI_SPCR0_MSB_BitS_MASK;
998        BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR0_MSB, lval);
999
1000        for (i=0; i<length; i+=2)
1001        {
1002            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 4),     (uint32_t)(pWriteData[i]) );
1003            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 4) + 4, (uint32_t)(pWriteData[i+1]) );
1004
1005            if( hChn->useUserDtlAndDsclk == true)
1006            {
1007                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK | SPI_CDRAM_BITSE;
1008            }
1009            else
1010            {
1011                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_BITSE;
1012            }
1013            lval &= ~(1 << hChn->pcs);
1014            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + ((i/2) * 4), lval );
1015        }
1016
1017        /* Skip for slower SPI device  */
1018        if( hChn->lastByteContinueEnable == false)
1019        {
1020            /*
1021             * Last one don't need to assert SS
1022             */
1023            if( hChn->useUserDtlAndDsclk == true)
1024            {
1025                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK | SPI_CDRAM_BITSE;
1026            }
1027            else
1028            {
1029                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_BITSE;
1030            }
1031            lval &= ~(1 << hChn->pcs);
1032            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + (((length/2) - 1) * 4), lval );
1033        }
1034
1035        /* Set queue pointers */
1036        BREG_Write32( hDev->hRegister, BCHP_MSPI_NEWQP, 0 );
1037        BREG_Write32( hDev->hRegister, BCHP_MSPI_ENDQP, (uint32_t)((length/2) - 1) );
1038    }
1039
1040    /* Start SPI transfer */
1041    lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR2);
1042    lval |= BCHP_MSPI_SPCR2_spe_MASK;
1043    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR2, lval);
1044
1045    /* Wait for SPI to finish */
1046    BSPI_CHK_RETCODE( retCode, BSPI_P_WaitForCompletion(hChn, length));
1047
1048    /* Transfer finished, clear SPIF bit */
1049    BKNI_EnterCriticalSection();
1050    BREG_Write32( hDev->hRegister, BCHP_MSPI_MSPI_STATUS, 0);
1051    BKNI_LeaveCriticalSection();
1052    /* Copy data to user buffer */
1053    if (hChn->bitsPerTxfr == 8)
1054    {
1055        /*
1056         * 8-bit transfer mode
1057         */
1058        for (i=0; i<length; i++)
1059        {
1060            lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_RXRAM00 + (i * 8) + 4);
1061            pReadData[i] = (uint8_t)lval;
1062        }
1063    }
1064    else
1065    {
1066        /*
1067         * 16-bit transfer mode
1068         */
1069        for (i=0; i<length; i+=2)
1070        {
1071            lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_RXRAM00 + (i * 4));
1072            pReadData[i] = (uint8_t)lval;
1073            lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_RXRAM00 + (i * 4) + 4);
1074            pReadData[i+1] = (uint8_t)lval;
1075        }
1076    }
1077
1078
1079done:
1080
1081    return retCode;
1082}
1083
1084BERR_Code BSPI_P_Write
1085(
1086    void *context,              /* Device channel handle */
1087    const uint8_t *pData,               /* pointer to data to write */
1088    size_t length               /* number of bytes to write */
1089)
1090{
1091    BSPI_Handle         hDev;
1092    BSPI_ChannelHandle  hChn;
1093    BERR_Code           retCode = BERR_SUCCESS;
1094    uint32_t            lval = 0, i;
1095
1096    hChn = (BSPI_ChannelHandle)context;
1097    BDBG_ASSERT( hChn );
1098    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1099
1100    if (((hChn->bitsPerTxfr == 8) && (length > MAX_SPI_XFER)) ||
1101        ((hChn->bitsPerTxfr == 16) && (length > (MAX_SPI_XFER * 2))))
1102    {
1103        retCode = BERR_INVALID_PARAMETER;
1104        goto done;
1105    }
1106
1107    if ((hChn->bitsPerTxfr == 16) && (length & 0x01))       /* if the length is odd, reject it */
1108    {
1109        retCode = BERR_INVALID_PARAMETER;
1110        goto done;
1111    }
1112
1113    hDev = hChn->hSpi;
1114
1115    /* Initialize the SPI clock */
1116    BSPI_P_SetClk (hChn, hChn->baud, hChn->clkConfig);
1117
1118    /* Fill the TX and CMD buffers */
1119    if (hChn->bitsPerTxfr == 8)
1120    {
1121        /*
1122         * 8-bit transfer mode
1123         */
1124        for (i=0; i<length; i++)
1125        {
1126            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 8), (uint32_t)(pData[i]) );
1127            if( hChn->useUserDtlAndDsclk == true)
1128            {
1129                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK;
1130            }
1131            else
1132            {
1133                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL;
1134            }
1135            lval &= ~(1 << hChn->pcs);
1136            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + (i * 4), lval );
1137        }
1138
1139        /* Skip for slower SPI device  */
1140        if( hChn->lastByteContinueEnable == false)
1141        {
1142            /*
1143             * Last one don't need to assert SS
1144             */
1145            if( hChn->useUserDtlAndDsclk == true)
1146            {
1147                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK;
1148            }
1149            else
1150            {
1151                lval = SPI_CDRAM_PCS_DISABLE_ALL;
1152            }
1153            lval &= ~(1 << hChn->pcs);
1154            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + ((length - 1) * 4), lval );
1155        }
1156
1157        /* Set queue pointers */
1158        BREG_Write32( hDev->hRegister, BCHP_MSPI_NEWQP, 0 );
1159        BREG_Write32( hDev->hRegister, BCHP_MSPI_ENDQP, (uint32_t)(length - 1) );
1160    }
1161    else
1162    {
1163        /*
1164         * 16-bit transfer mode
1165         */
1166        lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR0_MSB);
1167        lval &= ~BCHP_MSPI_SPCR0_MSB_BitS_MASK;
1168        BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR0_MSB, lval);
1169
1170        for (i=0; i<length; i+=2)
1171        {
1172            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 4),     (uint32_t)(pData[i]) );
1173            BREG_Write32( hDev->hRegister, BCHP_MSPI_TXRAM00 + (i * 4) + 4, (uint32_t)(pData[i+1]) );
1174
1175            if( hChn->useUserDtlAndDsclk == true)
1176            {
1177                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK | SPI_CDRAM_BITSE;
1178            }
1179            else
1180            {
1181                lval = SPI_CDRAM_CONT | SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_BITSE;
1182            }
1183            lval &= ~(1 << hChn->pcs);
1184            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + ((i/2) * 4), lval );
1185        }
1186
1187        /* Skip for slower SPI device  */
1188        if( hChn->lastByteContinueEnable == false)
1189        {
1190            /*
1191             * Last one don't need to assert SS
1192             */
1193            if( hChn->useUserDtlAndDsclk == true)
1194            {
1195                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_DT | SPI_CDRAM_DSCK | SPI_CDRAM_BITSE;
1196            }
1197            else
1198            {
1199                lval = SPI_CDRAM_PCS_DISABLE_ALL | SPI_CDRAM_BITSE;
1200            }
1201            lval &= ~(1 << hChn->pcs);
1202            BREG_Write32( hDev->hRegister, BCHP_MSPI_CDRAM00 + (((length/2) - 1) * 4), lval );
1203        }
1204
1205        /* Set queue pointers */
1206        BREG_Write32( hDev->hRegister, BCHP_MSPI_NEWQP, 0 );
1207        BREG_Write32( hDev->hRegister, BCHP_MSPI_ENDQP, (uint32_t)((length/2) - 1) );
1208    }
1209
1210    /* Start SPI transfer */
1211    lval = BREG_Read32( hDev->hRegister, BCHP_MSPI_SPCR2);
1212    lval |= BCHP_MSPI_SPCR2_spe_MASK;
1213    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR2, lval);
1214
1215    /* Wait for SPI to finish */
1216    BSPI_CHK_RETCODE( retCode, BSPI_P_WaitForCompletion(hChn, length));
1217
1218    /* Transfer finished, clear SPIF bit */
1219    BKNI_EnterCriticalSection();
1220    BREG_Write32( hDev->hRegister, BCHP_MSPI_MSPI_STATUS, 0);
1221    BKNI_LeaveCriticalSection();
1222
1223done:
1224
1225    return retCode;
1226}
1227
1228
1229void BSPI_P_SetClk(
1230    BSPI_ChannelHandle  hChn,           /* Device channel handle */
1231    uint32_t            baud,           /* baud rate */
1232    uint8_t             clkConfig       /* clock configuration */
1233    )
1234{
1235    BSPI_Handle hDev;
1236    uint32_t    lval;
1237    BERR_Code   retCode = BERR_SUCCESS;
1238
1239    BDBG_ASSERT( hChn );
1240    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1241
1242    hDev = hChn->hSpi;
1243
1244    if (baud > MAX_SPI_BAUD)
1245    {
1246        retCode = BERR_INVALID_PARAMETER;
1247        return;
1248    }
1249    lval = SPI_SYSTEM_CLK / (2 * baud);
1250    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR0_LSB, lval );
1251
1252    lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_SPCR0_MSB);
1253    lval &= ~(BCHP_MSPI_SPCR0_MSB_CPOL_MASK | BCHP_MSPI_SPCR0_MSB_CPHA_MASK);
1254    lval |= (BCHP_MSPI_SPCR0_MSB_MSTR_MASK | clkConfig);
1255    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR0_MSB, lval );
1256}
1257
1258static void BSPI_P_EnableInt_isr( BSPI_Handle hDev )
1259{
1260    uint32_t    lval;
1261
1262
1263    lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_SPCR2);
1264    lval |= BCHP_MSPI_SPCR2_spifie_MASK;
1265    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR2, lval );
1266
1267}
1268
1269static void BSPI_P_DisableInt_isr( BSPI_Handle hDev )
1270{
1271    uint32_t    lval;
1272
1273
1274    lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_SPCR2);
1275    lval &= ~BCHP_MSPI_SPCR2_spifie_MASK;
1276    BREG_Write32( hDev->hRegister, BCHP_MSPI_SPCR2, lval );
1277
1278}
1279
1280BERR_Code BSPI_P_WaitForCompletion
1281(
1282    BSPI_ChannelHandle  hChn,                           /* Device channel handle */
1283    uint32_t            numBytes                        /* number of bytes to transfer */
1284)
1285{
1286    BSPI_Handle         hDev;
1287    BERR_Code           retCode = BERR_SUCCESS;
1288    uint32_t            lval, timeoutMs, loopCnt;
1289
1290    hDev = hChn->hSpi;
1291
1292    /* Calculate the timeout value */
1293    lval = numBytes * 9;                        /* number of clks per byte, assume delay between each byte xfer accounts for 1 extra clock per byte */
1294    timeoutMs = (lval * 1000) / hChn->baud;     /* get timeout in milliseconds */
1295    timeoutMs = ((timeoutMs * 110) / 100) + 1;  /* add 10% fudge factor and round up */
1296
1297    if (hChn->intMode)
1298    {
1299        /*
1300         * Wait for event, set by ISR
1301         */
1302        BSPI_CHK_RETCODE (retCode, BKNI_WaitForEvent(hChn->hChnEvent, timeoutMs));
1303    }
1304    else
1305    {
1306        /*
1307         * Polling mode
1308         */
1309        loopCnt = ((timeoutMs * 1000) / SPI_POLLING_INTERVAL) + 1;
1310        while (1)
1311        {
1312            lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_MSPI_STATUS);
1313            if (lval & BCHP_MSPI_MSPI_STATUS_SPIF_MASK)
1314                break;
1315
1316            if (loopCnt == 0)
1317            {
1318                retCode = BERR_TIMEOUT;
1319                goto done;
1320            }
1321            BKNI_Delay(SPI_POLLING_INTERVAL);
1322            loopCnt--;
1323        }
1324    }
1325
1326done:
1327    return retCode;
1328}
1329
1330void BSPI_P_HandleInterrupt_Isr
1331(
1332    void *pParam1,                      /* Device channel handle */
1333    int parm2                           /* not used */
1334)
1335{
1336    BSPI_ChannelHandle  hChn;
1337    BSPI_Handle         hDev;
1338    uint32_t            lval;
1339
1340    hChn = (BSPI_ChannelHandle) pParam1;
1341    BDBG_ASSERT( hChn );
1342    BSTD_UNUSED(parm2);
1343
1344    hDev = hChn->hSpi;
1345
1346    /* Clear interrupt */
1347    lval = BREG_Read32(hDev->hRegister, BCHP_MSPI_MSPI_STATUS);
1348    lval &= ~BCHP_MSPI_MSPI_STATUS_SPIF_MASK;
1349    BREG_Write32(hDev->hRegister, BCHP_MSPI_MSPI_STATUS, lval);
1350
1351    BKNI_SetEvent( hChn->hChnEvent );
1352    return;
1353}
1354
1355
Note: See TracBrowser for help on using the repository browser.