@@ -43,13 +43,69 @@ static const SWM_Map SWM_SPI_MISO[] = {
43
43
44
44
// bit flags for used SPIs
45
45
static unsigned char spi_used = 0 ;
46
- static int get_available_spi (void )
46
+ static int get_available_spi (PinName mosi , PinName miso , PinName sclk , PinName ssel )
47
47
{
48
- int i ;
49
- for (i = 0 ; i < 2 ; i ++ ) {
50
- if ((spi_used & (1 << i )) == 0 )
51
- return i ;
48
+ if (spi_used == 0 ) {
49
+ return 0 ; // The first user
52
50
}
51
+
52
+ const SWM_Map * swm ;
53
+ uint32_t regVal ;
54
+
55
+ // Investigate if same pins as the used SPI0/1 - to be able to reuse it
56
+ for (int spi_n = 0 ; spi_n < 2 ; spi_n ++ ) {
57
+ if (spi_used & (1 <<spi_n )) {
58
+ if (sclk != NC ) {
59
+ swm = & SWM_SPI_SCLK [spi_n ];
60
+ regVal = LPC_SWM -> PINASSIGN [swm -> n ] & (0xFF << swm -> offset );
61
+ if (regVal != (sclk << swm -> offset )) {
62
+ // Existing pin is not the same as the one we want
63
+ continue ;
64
+ }
65
+ }
66
+
67
+ if (mosi != NC ) {
68
+ swm = & SWM_SPI_MOSI [spi_n ];
69
+ regVal = LPC_SWM -> PINASSIGN [swm -> n ] & (0xFF << swm -> offset );
70
+ if (regVal != (mosi << swm -> offset )) {
71
+ // Existing pin is not the same as the one we want
72
+ continue ;
73
+ }
74
+ }
75
+
76
+ if (miso != NC ) {
77
+ swm = & SWM_SPI_MISO [spi_n ];
78
+ regVal = LPC_SWM -> PINASSIGN [swm -> n ] & (0xFF << swm -> offset );
79
+ if (regVal != (miso << swm -> offset )) {
80
+ // Existing pin is not the same as the one we want
81
+ continue ;
82
+ }
83
+ }
84
+
85
+ if (ssel != NC ) {
86
+ swm = & SWM_SPI_SSEL [spi_n ];
87
+ regVal = LPC_SWM -> PINASSIGN [swm -> n ] & (0xFF << swm -> offset );
88
+ if (regVal != (ssel << swm -> offset )) {
89
+ // Existing pin is not the same as the one we want
90
+ continue ;
91
+ }
92
+ }
93
+
94
+ // The pins for the currently used SPIx are the same as the
95
+ // ones we want so we will reuse it
96
+ return spi_n ;
97
+ }
98
+ }
99
+
100
+ // None of the existing SPIx pin setups match the pins we want
101
+ // so the last hope is to select one unused SPIx
102
+ if ((spi_used & 1 ) == 0 ) {
103
+ return 0 ;
104
+ } else if ((spi_used & 2 ) == 0 ) {
105
+ return 1 ;
106
+ }
107
+
108
+ // No matching setup and no free SPIx
53
109
return -1 ;
54
110
}
55
111
@@ -58,7 +114,7 @@ static inline void spi_enable(spi_t *obj);
58
114
59
115
void spi_init (spi_t * obj , PinName mosi , PinName miso , PinName sclk , PinName ssel )
60
116
{
61
- int spi_n = get_available_spi ();
117
+ int spi_n = get_available_spi (mosi , miso , sclk , ssel );
62
118
if (spi_n == -1 ) {
63
119
error ("No available SPI" );
64
120
}
@@ -138,10 +194,10 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
138
194
obj -> spi -> CFG = tmp ;
139
195
140
196
// select frame length
141
- tmp = obj -> spi -> TXDATCTL ;
197
+ tmp = obj -> spi -> TXCTL ;
142
198
tmp &= ~(0xf << 24 );
143
199
tmp |= (LEN << 24 );
144
- obj -> spi -> TXDATCTL = tmp ;
200
+ obj -> spi -> TXCTL = tmp ;
145
201
146
202
spi_enable (obj );
147
203
}
@@ -181,14 +237,14 @@ static inline void spi_write(spi_t *obj, int value)
181
237
{
182
238
while (!spi_writeable (obj ));
183
239
// end of transfer
184
- obj -> spi -> TXDATCTL |= (1 << 20 );
185
- obj -> spi -> TXDAT = value ;
240
+ obj -> spi -> TXCTL |= (1 << 20 );
241
+ obj -> spi -> TXDAT = ( value & 0xffff ) ;
186
242
}
187
243
188
244
static inline int spi_read (spi_t * obj )
189
245
{
190
246
while (!spi_readable (obj ));
191
- return obj -> spi -> RXDAT ;
247
+ return obj -> spi -> RXDAT & 0xffff ; // Only the lower 16 bits contain data
192
248
}
193
249
194
250
int spi_busy (spi_t * obj )
@@ -210,7 +266,7 @@ int spi_slave_receive(spi_t *obj)
210
266
211
267
int spi_slave_read (spi_t * obj )
212
268
{
213
- return obj -> spi -> RXDAT ;
269
+ return obj -> spi -> RXDAT & 0xffff ; // Only the lower 16 bits contain data
214
270
}
215
271
216
272
void spi_slave_write (spi_t * obj , int value )
0 commit comments