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

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ba85153

Browse files
committed
drivers: Add ublox Nina-W10 WiFi/BT module driver.
* WiFi and Bluetooth drivers for Nina-W10 (esp32 based) WiFi module.
1 parent c70930f commit ba85153

File tree

5 files changed

+1393
-0
lines changed

5 files changed

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

0 commit comments

Comments
 (0)
0