@@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_PCA10090_LOG_LEVEL);
2121 */
2222
2323/* GPIO pins on Port 0 */
24+
2425#define INTERFACE0_U5 13 /* MCU interface pins 0 - 2 */
2526#define INTERFACE1_U6 24 /* MCU interface pins 3 - 5 */
2627#define UART1_VCOM_U7 12 /* Route nRF9160 UART1 to VCOM2 */
@@ -29,6 +30,7 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_PCA10090_LOG_LEVEL);
2930#define SWITCH2_U9 8
3031
3132/* GPIO pins on Port 1 */
33+
3234#define INTERFACE2_U21 10 /* COEX interface pins 6 - 8 */
3335#define UART0_VCOM_U14 14 /* Route nRF9160 UART0 to VCOM0 */
3436#define UART1_VCOM_U7 12 /* Route nRF9160 UART1 to VCOM2 */
@@ -53,12 +55,18 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_PCA10090_LOG_LEVEL);
5355 * | COEX2 | -- MCU Interface Pin 8 -- | P1.15 | COEX2_PH |
5456 */
5557
56- /* The following tables specify the -default- values for each pin.
57- * Thus, when configuring the pins if there is a one in this table,
58- * pull the pin to zero instead.
58+ __packed struct pin_config {
59+ u8_t pin ;
60+ u8_t val ;
61+ };
62+
63+ /* The following tables specify the configuration of each pin based on the
64+ * Kconfig options that drive it.
65+ * The switches have active-low logic, so when writing to the port we will
66+ * need to invert the value to match the IS_ENABLED() logic.
5967 */
6068
61- static const u8_t pins_on_p0 [][ 2 ] = {
69+ static const struct pin_config pins_on_p0 [] = {
6270 { INTERFACE0_U5 , IS_ENABLED (CONFIG_BOARD_PCA10090_INTERFACE0_ARDUINO ) },
6371 { INTERFACE1_U6 , IS_ENABLED (CONFIG_BOARD_PCA10090_INTERFACE1_TRACE ) },
6472 { UART1_VCOM_U7 , IS_ENABLED (CONFIG_BOARD_PCA10090_UART1_ARDUINO ) },
@@ -67,7 +75,7 @@ static const u8_t pins_on_p0[][2] = {
6775 { SWITCH2_U9 , IS_ENABLED (CONFIG_BOARD_PCA10090_SWITCH1_PHY ) },
6876};
6977
70- static const u8_t pins_on_p1 [][ 2 ] = {
78+ static const struct pin_config pins_on_p1 [] = {
7179 { INTERFACE2_U21 , IS_ENABLED (CONFIG_BOARD_PCA10090_INTERFACE2_COEX ) },
7280 { UART0_VCOM_U14 , IS_ENABLED (CONFIG_BOARD_PCA10090_UART0_VCOM ) },
7381 { UART1_VCOM_U7 , IS_ENABLED (CONFIG_BOARD_PCA10090_UART1_ARDUINO ) },
@@ -163,40 +171,171 @@ static void config_print(void)
163171 IS_ENABLED (CONFIG_BOARD_PCA10090_SWITCH1_ARDUINO ));
164172}
165173
166- static void configure_pins (struct device * port , const u8_t pins [][ 2 ],
167- size_t size )
174+ static int pins_configure (struct device * port , const struct pin_config cfg [ ],
175+ size_t pins )
168176{
169177 int err ;
170178
171- for (size_t i = 0 ; i < size ; i ++ ) {
172- err = gpio_pin_configure (port , pins [i ][0 ], GPIO_DIR_OUT );
173- __ASSERT (err == 0 , "Unable to configure pin %u" , pins [i ][0 ]);
174-
175- /* The pin tables contain the default values for each pin.
176- * Thus, if there is a one in the table, pull the pin to zero.
179+ /* Write to the pins before configuring them as output,
180+ * to make sure we are driving them to the correct level
181+ * right after they are configured.
182+ */
183+ for (size_t i = 0 ; i < pins ; i ++ ) {
184+ /* The swiches on the board are active low, so we need
185+ * to negate the IS_ENABLED() value from the tables.
177186 */
178- err = gpio_pin_write (port , pins [i ][0 ], !pins [i ][1 ]);
179- __ASSERT (err == 0 , "Unable to set pin %u to %u" , pins [i ][0 ],
180- !pins [i ][1 ]);
187+ err = gpio_pin_write (port , cfg [i ].pin , !cfg [i ].val );
188+ if (err ) {
189+ return cfg [i ].pin ;
190+ }
191+
192+ err = gpio_pin_configure (port , cfg [i ].pin , GPIO_DIR_OUT );
193+ if (err ) {
194+ return cfg [i ].pin ;
195+ }
196+
197+ LOG_DBG ("port %p, pin %u -> %u" ,
198+ port , cfg [i ].pin , !cfg [i ].val );
199+ }
200+
201+ return 0 ;
202+ }
203+
204+ static void chip_reset (struct device * gpio ,
205+ struct gpio_callback * cb , u32_t pins )
206+ {
207+ const u32_t stamp = k_cycle_get_32 ();
208+
209+ printk ("GPIO reset line asserted, device reset.\n" );
210+ printk ("Bye @ cycle32 %u\n" , stamp );
211+
212+ NVIC_SystemReset ();
213+ }
214+
215+ static void reset_pin_wait_low (struct device * port , u32_t pin )
216+ {
217+ int err ;
218+ u32_t val ;
219+
220+ /* Wait until the pin is pulled low */
221+ do {
222+ err = gpio_pin_read (port , pin , & val );
223+ } while (err == 0 && val != 0 );
224+ }
225+
226+ static int reset_pin_configure (struct device * p0 , struct device * p1 )
227+ {
228+ int err ;
229+ u32_t pin ;
230+ struct device * port = NULL ;
231+
232+ static struct gpio_callback gpio_ctx ;
233+
234+ /* MCU interface pins 0-2 */
235+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P0_17 )) {
236+ port = p0 ;
237+ pin = 17 ;
181238 }
239+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P0_20 )) {
240+ port = p0 ;
241+ pin = 20 ;
242+ }
243+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P0_15 )) {
244+ port = p0 ;
245+ pin = 15 ;
246+ }
247+ /* MCU interface pins 3-6 */
248+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P0_22 )) {
249+ port = p0 ;
250+ pin = 22 ;
251+ }
252+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P1_04 )) {
253+ port = p1 ;
254+ pin = 4 ;
255+ }
256+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET_P1_02 )) {
257+ port = p1 ;
258+ pin = 2 ;
259+ }
260+
261+ if (port == NULL ) {
262+ return - EINVAL ;
263+ }
264+
265+ err = gpio_pin_configure (port , pin ,
266+ GPIO_DIR_IN | GPIO_INT | GPIO_PUD_PULL_DOWN |
267+ GPIO_INT_ACTIVE_HIGH | GPIO_INT_EDGE );
268+ if (err ) {
269+ return err ;
270+ }
271+
272+ gpio_init_callback (& gpio_ctx , chip_reset , BIT (pin ));
273+
274+ err = gpio_add_callback (port , & gpio_ctx );
275+ if (err ) {
276+ return err ;
277+ }
278+
279+ err = gpio_pin_enable_callback (port , pin );
280+ if (err ) {
281+ return err ;
282+ }
283+
284+ /* Wait until the pin is pulled low before continuing.
285+ * This lets the other side ensure that they are ready.
286+ */
287+ LOG_INF ("GPIO reset line enabled on pin %s.%02u, holding.." ,
288+ port == p0 ? "P0" : "P1" , pin );
289+
290+ reset_pin_wait_low (port , pin );
291+
292+ return 0 ;
182293}
183294
184295static int init (struct device * dev )
185296{
297+ int rc ;
186298 struct device * p0 ;
187299 struct device * p1 ;
188300
189301 p0 = device_get_binding (DT_GPIO_P0_DEV_NAME );
190- __ASSERT (p0 , "Unable to find GPIO %s" , DT_GPIO_P0_DEV_NAME );
302+ if (!p0 ) {
303+ LOG_ERR ("GPIO device " DT_GPIO_P0_DEV_NAME "not found!" );
304+ return - EIO ;
305+ }
191306
192307 p1 = device_get_binding (DT_GPIO_P1_DEV_NAME );
193- __ASSERT (p1 , "Unable to find GPIO %s" , DT_GPIO_P1_DEV_NAME );
308+ if (!p1 ) {
309+ LOG_ERR ("GPIO device " DT_GPIO_P1_DEV_NAME " not found!" );
310+ return - EIO ;
311+ }
194312
195- configure_pins (p0 , pins_on_p0 , ARRAY_SIZE (pins_on_p0 ));
196- configure_pins (p1 , pins_on_p1 , ARRAY_SIZE (pins_on_p1 ));
313+ /* Configure pins on each port */
314+ rc = pins_configure (p0 , pins_on_p0 , ARRAY_SIZE (pins_on_p0 ));
315+ if (rc ) {
316+ LOG_ERR ("Error while configuring pin P0.%02d" , rc );
317+ return - EIO ;
318+ }
319+ rc = pins_configure (p1 , pins_on_p1 , ARRAY_SIZE (pins_on_p1 ));
320+ if (rc ) {
321+ LOG_ERR ("Error while configuring pin P1.%02d" , rc );
322+ return - EIO ;
323+ }
197324
198325 config_print ();
199326
327+ /* Make sure to configure the switches before initializing
328+ * the GPIO reset pin, so that we are connected to
329+ * the nRF9160 before enabling our interrupt.
330+ */
331+ if (IS_ENABLED (CONFIG_BOARD_PCA10090_NRF52840_RESET )) {
332+ rc = reset_pin_configure (p0 , p1 );
333+ if (rc ) {
334+ LOG_ERR ("Unable to configure reset pin, err %d" , rc );
335+ return - EIO ;
336+ }
337+ }
338+
200339 LOG_INF ("Board configured." );
201340
202341 return 0 ;
0 commit comments