8000 drivers: Add ublox Nina-W10 WiFi/BT module driver. · micropython/micropython@5f5d0c1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5f5d0c1

Browse files
committed
drivers: 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 0be3b91 commit 5f5d0c1

File tree

7 files changed

+1935
-0
lines changed

7 files changed

+1935
-0
lines changed

drivers/ninaw10/nina_bsp.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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 __NINA_BSP_H__
30+
#define __NINA_BSP_H__
31+
int nina_bsp_init(void);
32+
int nina_bsp_deinit(void);
33+
int nina_bsp_read_irq(void);
34+
int nina_bsp_spi_slave_select(uint32_t timeout);
35+
int nina_bsp_spi_slave_deselect(void);
36+
int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size);
37+
#endif // define __NINA_BSP_H__

drivers/ninaw10/nina_bt_hci.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
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+
#include "py/mphal.h"
30+
#if MICROPY_PY_BLUETOOTH && MICROPY_PY_NETWORK_NINAW10
31+
32+
#include <stdio.h>
33+
#include <string.h>
34+
35+
#include "py/runtime.h"
36+
#include "extmod/mpbthci.h"
37+
38+
#define HCI_COMMAND_PACKET (0x01)
39+
#define HCI_ACLDATA_PACKET (0x02)
40+
#define HCI_EVENT_PACKET (0x04)
41+
42+
#define HCI_COMMAND_COMPLETE (0x0e)
43+
#define HCI_COMMAND_TIMEOUT (3000)
44+
45+
#define OGF_LINK_CTL (0x01)
46+
#define OGF_HOST_CTL (0x03)
47+
48+
#define OCF_SET_EVENT_MASK (0x0001)
49+
#define OCF_RESET (0x0003)
50+
51+
#define error_printf(...) mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__)
52+
#define debug_printf(...) // mp_printf(&mp_plat_print, "nina_bt_hci.c: " __VA_ARGS__)
53+
54+
// Provided by the port, and also possibly shared with the stack.
55+
extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
56+
57+
static int nina_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
58+
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
59+
60+
buf[0] = HCI_COMMAND_PACKET;
61+
buf[1] = ocf;
62+
buf[2] = ogf << 2 | ocf >> 8;
63+
buf[3] = param_len;
64+
65+
if (param_len) {
66+
memcpy(buf + 4, param_buf, param_len);
67+
}
68+
69+
debug_printf("HCI Command: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
70+
71+
mp_bluetooth_hci_uart_write(buf, 4 + param_len);
72+
73+
// Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen).
74+
for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) {
75+
while (!mp_bluetooth_hci_uart_any()) {
76+
MICROPY_EVENT_POLL_HOOK
77+
// Timeout.
78+
if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) {
79+
error_printf("timeout waiting for HCI packet\n");
80+
return -1;
81+
}
82+
}
83+
84+
buf[i] = mp_bluetooth_hci_uart_readchar();
85+
86+
// There seems to be a sync issue with this fw/module.
87+
if (i == 0 && buf[0] == 0xFF) {
88+
continue;
89+
}
90+
91+
// Check for packet type.
92+
if (i == 0 && buf[0] != HCI_EVENT_PACKET) {
93+
error_printf("unexpected HCI packet: %02x\n", buf[0]);
94+
return -1;
95+
}
96+
97+
// Sanity check the packet parameters length.
98+
if (i == 2 && ((size += buf[2]) > sizeof(mp_bluetooth_hci_cmd_buf))) {
99+
error_printf("unexpected event packet length: %d\n", size);
100+
return -1;
101+
}
102+
103+
i++;
104+
}
105+
106+
// We're only looking for command complete events.
107+
if (buf[1] != HCI_COMMAND_COMPLETE || buf[4] != ocf || buf[5] != (ogf << 2 | ocf >> 8)) {
108+
error_printf("response mismatch: %02x %02x\n", buf[4], buf[5]);
109+
return -1;
110+
}
111+
112+
// Log event.
113+
debug_printf("HCI Event packet: %02x %02x %02x %02x %02x %02x %02x\n",
114+
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
115+
116+
// Status code.
117+
return buf[6];
118+
}
119+
120+
int mp_bluetooth_hci_controller_init(void) {
121+
// This is called immediately after the UART is initialised during stack initialisation.
122+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
123+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
124+
125+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0);
126+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
127+
mp_hal_delay_ms(100);
128+
129+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1);
130+
mp_hal_delay_ms(750);
131+
132+
// The UART must be re-initialize here because the GPIO1/RX pin is used initially
133+
// to reset the module in Bluetooth mode. This will change back the pin to UART RX.
134+
mp_bluetooth_hci_uart_init(0, 0);
135+
136+
// Send reset command
137+
return nina_hci_cmd(OGF_HOST_CTL, OCF_RESET, 0, NULL);
138+
// It seems that nothing else is needed for now.
139+
}
140+
141+
int mp_bluetooth_hci_controller_deinit(void) {
142+
// Reset module
143+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
144+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
145+
return 0;
146+
}
147+
#endif

drivers/ninaw10/nina_wifi_bsp.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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+
#include "py/mphal.h"
30+
#if MICROPY_PY_NETWORK_NINAW10
31+
32+
#include <stdint.h>
33+
#include <string.h>
34+
35+
#include "py/runtime.h"
36+
#include "modmachine.h"
37+
#include "extmod/machine_spi.h"
38+
#include "mpconfigboard.h"
39+
40+
#include "nina_bsp.h"
41+
#include "nina_wifi_drv.h"
42+
43+
#if NINA_DEBUG
44+
#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__)
45+
#else
46+
#define debug_printf(...)
47+
#endif
48+
49+
int nina_bsp_init(void) {
50+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
51+
mp_hal_pin_input(MICROPY_HW_NINA_ACK);
52+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
53+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO0);
54+
55+
// Reset module in WiFi mode
56+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
57+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1);
58+
59+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
60+
mp_hal_delay_ms(100);
61+
62+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 1);
63+
mp_hal_delay_ms(750);
64+
65+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 0);
66+
mp_hal_pin_input(MICROPY_HW_NINA_GPIO0);
67+
68+
// Initialize SPI.
69+
mp_obj_t args[] = {
70+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_ID),
71+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_BAUDRATE),
72+
};
73+
74+
MP_STATE_PORT(mp_wifi_spi) = machine_spi_type.make_new((mp_obj_t)&machine_spi_type, 2, 0, args);
75+
return 0;
76+
}
77+
78+
int nina_bsp_deinit(void) {
79+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO1);
80+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
81+
82+
mp_hal_pin_output(MICROPY_HW_NINA_RESET);
83+
mp_hal_pin_write(MICROPY_HW_NINA_RESET, 0);
84+
mp_hal_delay_ms(100);
85+
86+
mp_hal_pin_output(MICROPY_HW_NINA_GPIO0);
87+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO0, 1);
88+
return 0;
89+
}
90+
91+
int nina_bsp_read_irq(void) {
92+
return mp_hal_pin_read(MICROPY_HW_NINA_GPIO0);
93+
}
94+
95+
int nina_bsp_spi_slave_select(uint32_t timeout) {
96+
// Wait for ACK to go low.
97+
for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 1; mp_hal_delay_ms(1)) {
98+
if ((mp_hal_ticks_ms() - start) >= timeout) {
99+
return -1;
100+
}
101+
}
102+
103+
// Chip select.
104+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 0);
105+
106+
// Wait for ACK to go high.
107+
for (mp_uint_t start = mp_hal_ticks_ms(); mp_hal_pin_read(MICROPY_HW_NINA_ACK) == 0; mp_hal_delay_ms(1)) {
108+
if ((mp_hal_ticks_ms() - start) >= 100) {
109+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
110+
return -1;
111+
}
112+
}
113+
114+
return 0;
115+
}
116+
117+
int nina_bsp_spi_slave_deselect(void) {
118+
mp_hal_pin_write(MICROPY_HW_NINA_GPIO1, 1);
119+
return 0;
120+
}
121+
122+
int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) {
123+
mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi);
124+
((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer(mp_wifi_spi, size, tx_buf, rx_buf);
125+
#if NINA_DEBUG
126+
for (int i = 0; i < size; i++) {
127+
if (tx_buf) {
128+
debug_printf("0x%x ", tx_buf[i]);
129+
} else {
130+
debug_printf("0x%x ", rx_buf[i]);
131+
}
132+
}
133+
#endif
134+
return 0;
135+
}
136+
#endif // MICROPY_PY_NETWORK_NINAW10

0 commit comments

Comments
 (0)
0