|
1 // This component and the accompanying materials are made available |
|
2 // under the terms of the License "Eclipse Public License v1.0" |
|
3 // which accompanies this distribution, and is available |
|
4 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
5 // |
|
6 // Initial Contributors: |
|
7 // lukasz.forynski@gmail.com |
|
8 // |
|
9 // Contributors: |
|
10 // |
|
11 // Description: |
|
12 // omap3530/omap3530_drivers/spi/omap3530_spi.inl |
|
13 // |
|
14 // This file contains definitions to internal SPI implementation. |
|
15 // It is not intended to be exported - SPI registers must not be modified from outside of |
|
16 // the driver! |
|
17 // |
|
18 |
|
19 |
|
20 // This sets the CS line to inactive mode (Specify aActiveMode as appropriate for configuration) |
|
21 // The CS pin will be put back to the opposite mode - using GPIO.. |
|
22 inline void SetCsInactive(TInt aModule, TInt aChannel, TSpiSsPinMode aActiveMode) |
|
23 { |
|
24 //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels |
|
25 // set the pin to the opposite to the currently active CS mode.. |
|
26 TUint16 csPinOptions = aActiveMode == ESpiCSPinActiveLow ? KCsPinModeUp : KCsPinModeDown; |
|
27 const TPinConfig& csConf = ModulePinConfig[aModule].iCs[aChannel]; |
|
28 __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels |
|
29 |
|
30 // now switch the pin mode.. |
|
31 SCM::SetPadConfig(csConf.iAddress, csConf.iMswLsw, SCM::EMode4 | csPinOptions); // always go to mode 4 (gpio) |
|
32 } |
|
33 |
|
34 void SetCsActive(TInt aModule, TInt aChannel, TSpiSsPinMode aActiveMode) |
|
35 { |
|
36 //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels |
|
37 TUint16 csPinOptions = aActiveMode == ESpiCSPinActiveLow ? KCsPinModeUp : KCsPinModeDown; |
|
38 const TPinConfig &csConf = ModulePinConfig[aModule].iCs[aChannel]; |
|
39 __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels |
|
40 |
|
41 // now switch the pin mode back to the SPI |
|
42 SCM::SetPadConfig(csConf.iAddress, csConf.iMswLsw, csConf.iFlags | csPinOptions); // revert to intended mode |
|
43 } |
|
44 |
|
45 |
|
46 // Setup pad function for SPI pins.. |
|
47 void SetupSpiPins(TUint aSpiModule) |
|
48 { |
|
49 //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels |
|
50 const TSpiPinConfig& pinCnf = ModulePinConfig[aSpiModule]; |
|
51 SCM::SetPadConfig(pinCnf.iClk.iAddress, pinCnf.iClk.iMswLsw, pinCnf.iClk.iFlags); |
|
52 SCM::SetPadConfig(pinCnf.iSimo.iAddress, pinCnf.iSimo.iMswLsw, pinCnf.iSimo.iFlags); |
|
53 SCM::SetPadConfig(pinCnf.iSomi.iAddress, pinCnf.iSomi.iMswLsw, pinCnf.iSomi.iFlags); |
|
54 // Cs pins are set dynamically during operations. |
|
55 } |
|
56 |
|
57 // helper function - returns appropriate value for the register for a given mode |
|
58 inline TUint32 SpiClkMode(TSpiClkMode aClkMode) |
|
59 { |
|
60 // (POL) (PHA) |
|
61 // 0 0 Mode 0: spim_clk is active high and sampling occurs on the rising edge. |
|
62 // 0 1 Mode 1: spim_clk is active high and sampling occurs on the falling edge. |
|
63 // 1 0 Mode 2: spim_clk is active low and sampling occurs on the falling edge. |
|
64 // 1 1 Mode 3: spim_clk is active low and sampling occurs on the rising edge. |
|
65 |
|
66 TUint val = 0; |
|
67 switch(aClkMode) |
|
68 { |
|
69 //case ESpiPolarityLowRisingEdge: // Active high, odd edges |
|
70 /*val |= MCSPI_CHxCONF_POL;*/ // 0 (not set) |
|
71 /*val |= MCSPI_CHxCONF_PHA;*/ // 0 (not set) |
|
72 //break; // commented out - it's only for reference - there's nothing to change |
|
73 |
|
74 case ESpiPolarityLowFallingEdge: // Active high, even edges |
|
75 /*val |= MCSPI_CHxCONF_POL;*/ // 0 (not set) |
|
76 val |= MCSPI_CHxCONF_PHA; // 1 |
|
77 break; |
|
78 |
|
79 case ESpiPolarityHighFallingEdge: // Active low, odd edges |
|
80 val |= MCSPI_CHxCONF_POL; // 1 |
|
81 /*val |= MCSPI_CHxCONF_PHA;*/ // 0 (not set) |
|
82 break; |
|
83 |
|
84 case ESpiPolarityHighRisingEdge: // Active low, even edges |
|
85 val |= MCSPI_CHxCONF_POL; // 1 |
|
86 val |= MCSPI_CHxCONF_PHA; // 1 |
|
87 break; |
|
88 } |
|
89 return val; |
|
90 } |
|
91 |
|
92 // helper function - returns appropriate value for the register for a given frequency (or error->if not found) |
|
93 inline TInt SpiClkValue(TInt aClkSpeedHz) |
|
94 { |
|
95 for (TInt val = 0; val < 0xD; val++) // only loop through all possible values.. |
|
96 { |
|
97 if(MCSPI_K48MHz >> val == aClkSpeedHz) |
|
98 { |
|
99 return (val << 2); // return value ready for the register |
|
100 } |
|
101 } |
|
102 return KErrNotFound; |
|
103 } |
|
104 |
|
105 inline TInt SpiWordWidth(TSpiWordWidth aWidth) |
|
106 { |
|
107 TInt val = 0; |
|
108 switch(aWidth) |
|
109 { |
|
110 case ESpiWordWidth_8: val |= MCSPI_CHxCONF_WL(8); break; |
|
111 case ESpiWordWidth_10: val |= MCSPI_CHxCONF_WL(10); break; |
|
112 case ESpiWordWidth_12: val |= MCSPI_CHxCONF_WL(12); break; |
|
113 case ESpiWordWidth_16: val |= MCSPI_CHxCONF_WL(16); break; |
|
114 // case ESpiWordWidth_32: val |= MCSPI_CHxCONF_WL(32); break; // TODO uncomment when fix for Bug 3665 is released |
|
115 } |
|
116 return val; |
|
117 } |
|
118 |