Skip to content

Commit 46dbc90

Browse files
authored
Merge pull request #6234 from marcuschangarm/feature-pinmap
[feature-nrf528xx] Extended PeripheralPins and pinmap for NRF52 series
2 parents bda6273 + b4d1ec5 commit 46dbc90

File tree

5 files changed

+472
-0
lines changed

5 files changed

+472
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "pinmap_ex.h"
18+
#include "mbed_toolchain.h"
19+
20+
/* Default mapping between I2C pins and I2C instance.
21+
* Can be overwritten by user.
22+
*/
23+
MBED_WEAK const PinMapI2C PinMap_I2C[1] = {
24+
{NC, NC, NC}
25+
};
26+
27+
/* Default mapping between SPI pins and SPI instance.
28+
* Can be overwritten by user.
29+
*/
30+
MBED_WEAK const PinMapSPI PinMap_SPI[1] = {
31+
{NC, NC, NC, NC}
32+
};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "object_owners.h"
18+
19+
#include "nrf.h"
20+
#include "nrf_peripherals.h"
21+
22+
#include <stdio.h>
23+
24+
#define SPI2C_INSTANCES SPI_COUNT
25+
26+
static void * nordic_spi2c_owners[SPI2C_INSTANCES] = { NULL, NULL, NULL };
27+
28+
/**
29+
* Brief Set instance owner for the SPI/I2C peripheral.
30+
*
31+
* Parameter instance The instance.
32+
* Parameter object The object.
33+
*/
34+
void object_owner_spi2c_set(int instance, void *object)
35+
{
36+
if (instance < SPI2C_INSTANCES) {
37+
nordic_spi2c_owners[instance] = object;
38+
}
39+
}
40+
41+
/**
42+
* Brief Get instance owner for the SPI/I2C peripheral.
43+
*
44+
* Parameter instance The instance.
45+
*
46+
* Return Pointer to the object owning the instance.
47+
*/
48+
void * object_owner_spi2c_get(int instance)
49+
{
50+
void *object = (void *) 0xFFFFFFFF;
51+
52+
if (instance < SPI2C_INSTANCES) {
53+
object = nordic_spi2c_owners[instance];
54+
}
55+
56+
return object;
57+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef OBJECT_OWNERS_H
18+
#define OBJECT_OWNERS_H
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
/**
25+
* @brief Set instance owner for the SPI/I2C peripheral.
26+
*
27+
* @param[in] instance The instance.
28+
* @param object The object.
29+
*/
30+
void object_owner_spi2c_set(int instance, void *object);
31+
32+
/**
33+
* @brief Get instance owner for the SPI/I2C peripheral.
34+
*
35+
* @param[in] instance The instance.
36+
*
37+
* @return Pointer to the object owning the instance.
38+
*/
39+
void * object_owner_spi2c_get(int instance);
40+
41+
#ifdef __cplusplus
42+
}
43+
#endif
44+
45+
#endif
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "pinmap_ex.h"
18+
19+
#include "mbed_toolchain.h"
20+
#include "nrf.h"
21+
#include "nrf_peripherals.h"
22+
23+
#include <stdio.h>
24+
25+
#if 0
26+
#define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0)
27+
#else
28+
#define DEBUG_PRINTF(...) {}
29+
#endif
30+
31+
/* Define number of instances */
32+
#define NORDIC_TWI_COUNT TWI_COUNT
33+
#define NORDIC_SPI_COUNT SPI_COUNT
34+
35+
/* Define which instance to return when there are no free instances left.
36+
* The Mbed HAL API doesn't provide a way for signaling initialization errors
37+
* so we return the default value. Any instance conflicts must be handled
38+
* by the driver implementation.
39+
*/
40+
#define DEFAULT_I2C_INSTANCE 0 // SPI counts down, choose instance furthest away
41+
#define DEFAULT_SPI_INSTANCE (SPI_COUNT - 1) // I2C counts up, choose instance furthers away
42+
43+
/* Internal data structure shared between SPI and I2C to keep track of allocated
44+
* instances. The data structure is shared to reflect the hardware sharing.
45+
*/
46+
typedef struct {
47+
PinName locaction0;
48+
PinName locaction1;
49+
PinName locaction2;
50+
} spi2c_t;
51+
52+
static spi2c_t nordic_internal_spi2c[3] = {
53+
{NC, NC, NC},
54+
{NC, NC, NC},
55+
{NC, NC, NC},
56+
};
57+
58+
/**
59+
* Brief Find hardware instance for the provided I2C pins.
60+
*
61+
* The function will search the PeripheralPin map for a pre-allocated
62+
* assignment. If none is found the allocation map will be searched
63+
* to see if the same pins have been assigned an instance before.
64+
*
65+
* If no assignement is found and there is an empty slot left in the
66+
* map, the pins are stored in the map and the hardware instance is
67+
* returned.
68+
*
69+
* If no free instances are available, the default instance is returned.
70+
*
71+
* Parameter sda sda pin.
72+
* Parameter scl scl pin.
73+
*
74+
* Return Hardware instance associated with provided pins.
75+
*/
76+
int pin_instance_i2c(PinName sda, PinName scl)
77+
{
78+
int instance = NC;
79+
80+
/* Search pin map for pre-allocated instance */
81+
for (size_t index = 0;
82+
!((PinMap_I2C[index].sda == NC) &&
83+
(PinMap_I2C[index].scl == NC));
84+
index++) {
85+
86+
/* Compare pins to entry. */
87+
if ((PinMap_I2C[index].sda == sda) &&
88+
(PinMap_I2C[index].scl == scl)) {
89+
90+
DEBUG_PRINTF("found: %d %d %d\r\n", sda, scl, PinMap_I2C[index].instance);
91+
92+
/* Instance found, save result. */
93+
instance = PinMap_I2C[index].instance;
94+
95+
/* Lock out entry in map to prevent SPI from grabbing it. */
96+
nordic_internal_spi2c[instance].locaction0 = sda;
97+
nordic_internal_spi2c[instance].locaction1 = scl;
98+
nordic_internal_spi2c[instance].locaction2 = NC;
99+
break;
100+
}
101+
}
102+
103+
/* No instance was found in static map. */
104+
if (instance == NC) {
105+
106+
/* Search dynamic map for entry. */
107+
for (size_t index = 0; index < NORDIC_TWI_COUNT; index++) {
108+
109+
/* Pins match previous dynamic allocation, return instance. */
110+
if ((nordic_internal_spi2c[index].locaction0 == sda) &&
111+
(nordic_internal_spi2c[index].locaction1 == scl) &&
112+
(nordic_internal_spi2c[index].locaction2 == NC)) {
113+
114+
instance = index;
115+
break;
116+
}
117+
}
118+
}
119+
120+
/* No instance was found in dynamic map. */
121+
if (instance == NC) {
122+
123+
/* Search dynamic map for empty slot. */
124+
for (size_t index = 0; index < NORDIC_TWI_COUNT; index++) {
125+
126+
/* Empty slot found, reserve slot by storing pins. */
127+
if ((nordic_internal_spi2c[index].locaction0 == NC) &&
128+
(nordic_internal_spi2c[index].locaction1 == NC) &&
129+
(nordic_internal_spi2c[index].locaction2 == NC)) {
130+
131+
nordic_internal_spi2c[index].locaction0 = sda;
132+
nordic_internal_spi2c[index].locaction1 = scl;
133+
134+
instance = index;
135+
break;
136+
}
137+
}
138+
}
139+
140+
#if defined(DEFAULT_I2C_INSTANCE)
141+
/* Exhausted all options. Return default value. */
142+
if (instance == NC) {
143+
instance = DEFAULT_I2C_INSTANCE;
144+
}
145+
#endif
146+
147+
DEBUG_PRINTF("I2C: %d %d %d\r\n", sda, scl, instance);
148+
149+
return instance;
150+
}
151+
152+
/**
153+
* Brief Find hardware instance for the provided SPI pins.
154+
*
155+
* The function will search the PeripheralPin map for a pre-allocated
156+
* assignment. If none is found the allocation map will be searched
157+
* to see if the same pins have been assigned an instance before.
158+
*
159+
* If no assignement is found and there is an empty slot left in the
160+
* map, the pins are stored in the map and the hardware instance is
161+
* returned.
162+
*
163+
* If no free instances are available, the default instance is returned.
164+
*
165+
* Parameter mosi mosi pin.
166+
* Parameter miso miso pin.
167+
* Parameter clk clk pin.
168+
*
169+
* Return Hardware instance associated with provided pins.
170+
*/
171+
int pin_instance_spi(PinName mosi, PinName miso, PinName clk)
172+
{
173+
int instance = NC;
174+
175+
/* Search pin map for pre-allocated instance */
176+
for (size_t index = 0;
177+
!((PinMap_SPI[index].mosi == NC) &&
178+
(PinMap_SPI[index].miso == NC) &&
179+
(PinMap_SPI[index].clk == NC));
180+
index++) {
181+
182+
DEBUG_PRINTF("search: %d %d %d\r\n", PinMap_SPI[index].mosi, PinMap_SPI[index].miso, PinMap_SPI[index].clk);
183+
184+
/* Compare pins to entry. */
185+
if ((PinMap_SPI[index].mosi == mosi) &&
186+
(PinMap_SPI[index].miso == miso) &&
187+
(PinMap_SPI[index].clk == clk)) {
188+
189+
DEBUG_PRINTF("found: %d %d %d %d\r\n", mosi, miso, clk, PinMap_SPI[index].instance);
190+
191+
/* Foung instance, save result. */
192+
instance = PinMap_SPI[index].instance;
193+
194+
/* Lock out entry in map to prevent I2C from grabbing it. */
195+
nordic_internal_spi2c[instance].locaction0 = mosi;
196+
nordic_internal_spi2c[instance].locaction1 = miso;
197+
nordic_internal_spi2c[instance].locaction2 = clk;
198+
break;
199+
}
200+
}
201+
202+
/* No instance was found in static map. */
203+
if (instance == NC) {
204+
205+
/* Search dynamic map for entry. */
206+
for (int index = NORDIC_SPI_COUNT - 1; index > -1; index--) {
207+
if ((nordic_internal_spi2c[index].locaction0 == mosi) &&
208+
(nordic_internal_spi2c[index].locaction1 == miso) &&
209+
(nordic_internal_spi2c[index].locaction2 == clk)) {
210+
211+
instance = index;
212+
break;
213+
}
214+
}
215+
}
216+
217+
/* No instance was found in dynamic map. */
218+
if (instance == NC) {
219+
220+
/* Search dynamic map for empty slot. */
221+
for (int index = NORDIC_SPI_COUNT - 1; index > -1; index--) {
222+
223+
/* Empty slot found, reserve slot by storing pins. */
224+
if ((nordic_internal_spi2c[index].locaction0 == NC) &&
225+
(nordic_internal_spi2c[index].locaction1 == NC) &&
226+
(nordic_internal_spi2c[index].locaction2 == NC)) {
227+
228+
nordic_internal_spi2c[index].locaction0 = mosi;
229+
nordic_internal_spi2c[index].locaction1 = miso;
230+
nordic_internal_spi2c[index].locaction2 = clk;
231+
232+
instance = index;
233+
break;
234+
}
235+
}
236+
}
237+
238+
#if defined(DEFAULT_SPI_INSTANCE)
239+
/* Exhausted all options. Return default value. */
240+
if (instance == NC) {
241+
instance = DEFAULT_SPI_INSTANCE;
242+
}
243+
#endif
244+
245+
DEBUG_PRINTF("SPI: %d %d %d %d\r\n", mosi, miso, clk, instance);
246+
247+
return instance;
248+
}

0 commit comments

Comments
 (0)