Skip to content

Commit 43079aa

Browse files
iabdalkaderdpgeorge
authored andcommitted
drivers/ninaw10: Add ublox Nina-W10 WiFi/BT module driver.
- Add WiFi/BT drivers for ublox Nina-W10 (esp32 based) module. - Add ublox Nina-W10 Python module in extmod.
1 parent b6dbbbe commit 43079aa

7 files changed

Lines changed: 1950 additions & 0 deletions

File tree

drivers/ninaw10/nina_bsp.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* This file is part of the OpenMV project, https://openmv.io.
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
7+
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*
27+
* NINA-W10 driver BSP.
28+
*/
29+
#ifndef MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H
30+
#define MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H
31+
32+
int nina_bsp_init(void);
33+
int nina_bsp_deinit(void);
34+
int nina_bsp_read_irq(void);
35+
int nina_bsp_spi_slave_select(uint32_t timeout);
36+
int nina_bsp_spi_slave_deselect(void);
37+
int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size);
38+
39+
#endif // MICROPY_INCLUDED_DRIVERS_NINAW10_NINA_BSP_H

drivers/ninaw10/nina_bt_hci.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* This file is part of the OpenMV project, https://openmv.io.
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
7+
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*
27+
* NINA-W10 Bluetooth HCI driver.
28+
*/
29+
30+
#include "py/mphal.h"
31+
32+
#if MICROPY_PY_BLUETOOTH && MICROPY_PY_NETWORK_NINAW10
33+
34+
#include <stdio.h>
35+
#include <string.h>
36+
37+
#include "py/runtime.h"
38+
#include "extmod/mpbthci.h"
39+
40+
#define HCI_COMMAND_PACKET (0x01)
41+
#define HCI_ACLDATA_PACKET (0x02)
42+
#define HCI_EVENT_PACKET (0x04)
43+
44+
#define HCI_COMMAND_COMPLETE (0x0e)
45+
#define HCI_COMMAND_TIMEOUT (3000)
46+
47+
#define OGF_LINK_CTL (0x01)
48+
#define OGF_HOST_CTL (0x03)
49+
50+
#define OCF_SET_EVENT_MASK (0x0001)
51+
#define OCF_RESET (0x0003)
52+
53+
#define error_printf(...) mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__)
54+
#define debug_printf(...) // mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__)
55+
56+
// Provided by the port, and also possibly shared with the stack.
57+
extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
58+
59+
static int nina_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
60+
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
61+
62+
buf[0] = HCI_COMMAND_PACKET;
63+
buf[1] = ocf;
64+
buf[2] = ogf << 2 | ocf >> 8;
65+
buf[3] = param_len;
66+
67+
if (param_len) {
68+
memcpy(buf + 4, param_buf, param_len);
69+
}
70+
71+
debug_printf("HCI Command: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
72+
73+
mp_bluetooth_hci_uart_write(buf, 4 + param_len);
74+
75+
// Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen).
76+
for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) {
77+
while (!mp_bluetooth_hci_uart_any()) {
78+
MICROPY_EVENT_POLL_HOOK
79+
// Timeout.
80+
if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) {
81+
error_printf("timeout waiting for HCI packet\n");
82+
return -1;
83+
}
84+
}
85+
86+
buf[i] = mp_bluetooth_hci_uart_readchar();
87+
88+
// There seems to be a sync issue with this fw/module.
89+
if (i == 0 && buf[0] == 0xFF) {
90+
continue;
91+
}
92+
93+
// Check for packet type.
94+
if (i == 0 && buf[0] != HCI_EVENT_PACKET) {
95+
error_printf("unexpected HCI packet: %02x\n", buf[0]);
96+
return -1;
97+
}
98+
99+
// Sanity check the packet parameters length.
100+
if (i == 2 && ((size += buf[2]) > sizeof(mp_bluetooth_hci_cmd_buf))) {
101+
error_printf("unexpected event packet length: %d\n", size);
102+
return -1;
103+
}
104+
105+
i++;
106+
}
107+
108+
// We're only looking for command complete events.
109+
if (buf[1] != HCI_COMMAND_COMPLETE || buf[4] != ocf || buf[5] != (ogf << 2 | ocf >> 8)) {
110+
error_printf("response mismatch: %02x %02x\n", buf[4], buf[5]);
111+
return -1;
112+
}
113+
114+
// Log event.
115+
debug_printf("HCI Event packet: %02x %02x %02x %02x %02x %02x %02x\n",
116+
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
117+
118+
// Status code.
119+
return buf[6];
120+
}
121+
122+
int mp_bluetooth_hci_controller_init(void) {
123+
// This is called immediately after the UART is initialised during stack initialisation.
124+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
125+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
126+
127+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0);
128+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
129+
mp_hal_delay_ms(100);
130+
131+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1);
132+
mp_hal_delay_ms(750);
133+
134+
// The UART must be re-initialize here because the GPIO1/RX pin is used initially
135+
// to reset the module in Bluetooth mode. This will change back the pin to UART RX.
136+
mp_bluetooth_hci_uart_init(0, 0);
137+
138+
// Send reset command
139+
return nina_hci_cmd(OGF_HOST_CTL, OCF_RESET, 0, NULL);
140+
// It seems that nothing else is needed for now.
141+
}
142+
143+
int mp_bluetooth_hci_controller_deinit(void) {
144+
// Reset module
145+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
146+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
147+
return 0;
148+
}
149+
150+
#endif

drivers/ninaw10/nina_wifi_bsp.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* This file is part of the OpenMV project, https://openmv.io.
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
7+
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*
27+
* NINA-W10 driver BSP implementation.
28+
*/
29+
30+
#include "py/mphal.h"
31+
32+
#if MICROPY_PY_NETWORK_NINAW10
33+
34+
#include <stdint.h>
35+
#include <string.h>
36+
37+
#include "py/runtime.h"
38+
#include "modmachine.h"
39+
#include "extmod/machine_spi.h"
40+
#include "mpconfigboard.h"
41+
42+
#include "nina_bsp.h"
43+
#include "nina_wifi_drv.h"
44+
45+
#if NINA_DEBUG
46+
#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__)
47+
#else
48+
#define debug_printf(...)
49+
#endif
50+
51+
int nina_bsp_init(void) {
52+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
53+
mp_hal_pin_input(MICROPY_HW_NINA_ACK);
54+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
55+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO0);
56+
57+
// Reset module in WiFi mode
58+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
59+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1);
60+
61+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
62+
mp_hal_delay_ms(100);
63+
64+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1);
65+
mp_hal_delay_ms(750);
66+
67+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 0);
68+
mp_hal_pin_input(MICROPY_HW_NINA_GPIO0);
69+
70+
// Initialize SPI.
71+
mp_obj_t args[] = {
72+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_ID),
73+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_BAUDRATE),
74+
};
75+
76+
MP_STATE_PORT(mp_wifi_spi) = machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 0, args);
77+
return 0;
78+
}
79+
80+
int nina_bsp_deinit(void) {
81+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
82+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
83+
84+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
85+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
86+
mp_hal_delay_ms(100);
87+
88+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO0);
89+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1);
90+
return 0;
91+
}
92+
93+
int nina_bsp_read_irq(void) {
94+
return mp_hal_pin_read(MICROPY_HW_NINA_GPIO0);
95+
}
96+
97+
int nina_bsp_spi_slave_select(uint32_t timeout) {
98+
// Wait for ACK to go low.
99+
for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 1; mp_hal_delay_ms(1)) {
100+
if ((mp_hal_ticks_ms() - start) >= timeout) {
101+
return -1;
102+
}
103+
}
104+
105+
// Chip select.
106+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0);
107+
108+
// Wait for ACK to go high.
109+
for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 0; mp_hal_delay_ms(1)) {
110+
if ((mp_hal_ticks_ms() - start) >= 100) {
111+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
112+
return -1;
113+
}
114+
}
115+
116+
return 0;
117+
}
118+
119+
int nina_bsp_spi_slave_deselect(void) {
120+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
121+
return 0;
122+
}
123+
124+
int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) {
125+
mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi);
126+
((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer(mp_wifi_spi, size, tx_buf, rx_buf);
127+
#if NINA_DEBUG
128+
for (int i = 0; i < size; i++) {
129+
if (tx_buf) {
130+
debug_printf("0x%x ", tx_buf[i]);
131+
} else {
132+
debug_printf("0x%x ", rx_buf[i]);
133+
}
134+
}
135+
#endif
136+
return 0;
137+
}
138+
139+
#endif // MICROPY_PY_NETWORK_NINAW10

0 commit comments

Comments
 (0)