Merge pull request #126 from pimoroni/pico-wireless

C++/MicroPython Support & Examples for Pico Wireless
This commit is contained in:
Philip Howard 2021-04-22 13:40:59 +01:00 committed by GitHub
commit 7776536d83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 4842 additions and 2 deletions

View File

@ -1,3 +1,4 @@
add_subdirectory(esp32spi)
add_subdirectory(st7789)
add_subdirectory(msa301)
add_subdirectory(rv3028)

View File

@ -0,0 +1 @@
include(esp32spi.cmake)

View File

@ -0,0 +1,13 @@
set(DRIVER_NAME esp32spi)
add_library(${DRIVER_NAME} INTERFACE)
target_sources(${DRIVER_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp
${CMAKE_CURRENT_LIST_DIR}/spi_drv.cpp
${CMAKE_CURRENT_LIST_DIR}/ip_address.cpp
)
target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_spi)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,222 @@
#pragma once
#include <string.h>
#include <string>
#include "pico/stdlib.h"
#include "spi_drv.hpp"
#include "ip_address.hpp"
#define WARN(message) {}
#define WL_FW_VER_LENGTH 6
#define WIFI_SPI_ACK 1
#define WIFI_SPI_ERR 0xFF
// Maxmium number of socket
#define WIFI_MAX_SOCK_NUM 10
// Socket not available constant
#define SOCK_NOT_AVAIL 255
// Default state value for Wifi state field
#define NA_STATE -1
//Maximum number of attempts to establish wifi connection
#define WL_MAX_ATTEMPT_CONNECTION 10
enum wl_ping_result_t {
WL_PING_DEST_UNREACHABLE = -1,
WL_PING_TIMEOUT = -2,
WL_PING_UNKNOWN_HOST = -3,
WL_PING_ERROR = -4
};
enum wl_status_t {
WL_NO_SHIELD = 255,
WL_NO_MODULE = WL_NO_SHIELD,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL,
WL_SCAN_COMPLETED,
WL_CONNECTED,
WL_CONNECT_FAILED,
WL_CONNECTION_LOST,
WL_DISCONNECTED,
WL_AP_LISTENING,
WL_AP_CONNECTED,
WL_AP_FAILED
};
enum wl_tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_CCMP = 4,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8,
ENC_TYPE_UNKNOWN = 255
};
enum wl_error_code_t {
WL_FAILURE = -1,
WL_SUCCESS = 1,
};
enum sv_protocol_mode {
TCP_MODE,
UDP_MODE,
TLS_MODE,
UDP_MULTICAST_MODE,
TLS_BEARSSL_MODE
};
#define KEY_IDX_LEN 1
namespace pimoroni {
class Esp32Spi {
//--------------------------------------------------
// Constants
//--------------------------------------------------
public:
static const uint8_t INPUT = 0;
static const uint8_t OUTPUT = 1;
static const uint8_t INPUT_PULLUP = 2;
//--------------------------------------------------
// Variables
//--------------------------------------------------
private:
SpiDrv driver;
char network_ssid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
// Firmware version string in the format a.b.c
char fw_version[WL_FW_VER_LENGTH];
// Settings of current selected network
char ssid[WL_SSID_MAX_LENGTH];
uint8_t bssid[WL_MAC_ADDR_LENGTH];
uint8_t mac[WL_MAC_ADDR_LENGTH];
uint8_t local_ip[WL_IPV4_LENGTH];
uint8_t subnet_mask[WL_IPV4_LENGTH];
uint8_t gateway_ip[WL_IPV4_LENGTH];
//--------------------------------------------------
// Methods
//--------------------------------------------------
public:
virtual bool init();
//--------------------------------------------------
//From https://github.com/adafruit/WiFiNINA/blob/master/src/utility/wifi_drv.cpp
//--------------------------------------------------
void get_network_data(uint8_t *ip_out, uint8_t *mask_out, uint8_t *gwip_out);
void get_remote_data(uint8_t sock, uint8_t *ip_out, uint8_t *port_out);
int8_t wifi_set_network(const std::string ssid);
int8_t wifi_set_passphrase(const std::string ssid, const std::string passphrase);
int8_t wifi_set_key(const std::string ssid, uint8_t key_idx, const std::string key);
void config(uint8_t valid_params, uint32_t local_ip, uint32_t gateway, uint32_t subnet);
void set_dns(uint8_t valid_params, uint32_t dns_server1, uint32_t dns_server2);
void set_hostname(std::string hostname);
int8_t disconnect();
uint8_t get_connection_status();
uint8_t* get_mac_address();
void get_ip_address(IPAddress &ip_out);
void get_subnet_mask(IPAddress &mask_out);
void get_gateway_ip(IPAddress &ip_out);
std::string get_current_ssid();
uint8_t* get_current_bssid();
int32_t get_current_rssi();
uint8_t get_current_encryption_type();
int8_t start_scan_networks();
uint8_t get_scan_networks();
const char* get_ssid_networks(uint8_t network_item);
uint8_t get_enc_type_networks(uint8_t network_item);
uint8_t* get_bssid_networks(uint8_t network_item, uint8_t* bssid_out);
uint8_t get_channel_networks(uint8_t network_item);
int32_t get_rssi_networks(uint8_t network_item);
bool req_host_by_name(const std::string hostname);
bool get_host_by_name(IPAddress& ip_out);
bool get_host_by_name(const std::string hostname, IPAddress& ip_out);
const char* get_fw_version();
uint32_t get_time();
void set_power_mode(uint8_t mode);
int8_t wifi_set_ap_network(const std::string ssid, uint8_t channel);
int8_t wifi_set_ap_passphrase(const std::string ssid, const std::string passphrase, uint8_t channel);
int16_t ping(uint32_t ip_address, uint8_t ttl);
void debug(uint8_t on);
float get_temperature();
void pin_mode(uint8_t pin, uint8_t mode);
void digital_write(uint8_t pin, uint8_t value);
void analog_write(uint8_t pin, uint8_t value);
bool digital_read(uint8_t pin);
uint16_t analog_read(uint8_t pin, uint8_t atten = 3);
//--------------------------------------------------
//From https://github.com/adafruit/WiFiNINA/blob/master/src/utility/server_drv.cpp
//--------------------------------------------------
void start_server(uint16_t port, uint8_t sock, uint8_t protocol_mode = TCP_MODE);
void start_server(uint32_t ip_address, uint16_t port, uint8_t sock, uint8_t protocol_mode = TCP_MODE);
void start_client(uint32_t ip_address, uint16_t port, uint8_t sock, uint8_t protocol_mode = TCP_MODE);
void start_client(const std::string host, uint32_t ip_address, uint16_t port, uint8_t sock, uint8_t protocol_mode = TCP_MODE);
void stop_client(uint8_t sock);
uint8_t get_server_state(uint8_t sock);
uint8_t get_client_state(uint8_t sock);
uint16_t avail_data(uint8_t sock);
uint8_t avail_server(uint8_t sock);
bool get_data(uint8_t sock, uint8_t *data_out, uint8_t peek);
bool get_data_buf(uint8_t sock, uint8_t *data_out, uint16_t *data_len_out);
bool insert_data_buf(uint8_t sock, const uint8_t *data_in, uint16_t len);
bool send_udp_data(uint8_t sock);
uint16_t send_data(uint8_t sock, const uint8_t *data_in, uint16_t len);
uint8_t check_data_sent(uint8_t sock);
uint8_t get_socket();
//--------------------------------------------------
void wifi_set_ent_identity(const std::string identity);
void wifi_set_ent_username(const std::string username);
void wifi_set_ent_password(const std::string password);
void wifi_set_ent_enable();
};
}

View File

@ -0,0 +1,62 @@
#include "ip_address.hpp"
namespace pimoroni {
IPAddress::IPAddress() {
addr.dword = 0;
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
addr.bytes[0] = first_octet;
addr.bytes[1] = second_octet;
addr.bytes[2] = third_octet;
addr.bytes[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address) {
addr.dword = address;
}
IPAddress::IPAddress(const uint8_t *address) {
addr.bytes[0] = address[0];
addr.bytes[1] = address[1];
addr.bytes[2] = address[2];
addr.bytes[3] = address[3];
}
bool IPAddress::operator==(const IPAddress &address) const {
return (addr.dword == address.addr.dword);
}
bool IPAddress::operator==(const uint32_t &address) const {
return (addr.dword == address);
}
uint8_t IPAddress::operator[](int index) const {
return addr.bytes[index];
}
uint8_t& IPAddress::operator[](int index) {
return addr.bytes[index];
}
IPAddress& IPAddress::operator=(uint32_t address) {
addr.dword = address;
return *this;
}
IPAddress::operator uint32_t() const {
return addr.dword;
}
std::string IPAddress::to_string() const {
char buf[16] = {0};
snprintf(buf, 16, "%d.%d.%d.%d", addr.bytes[0], addr.bytes[1], addr.bytes[2], addr.bytes[3]);
return std::string(buf, 16);
}
const uint8_t* IPAddress::to_bytes() const {
return addr.bytes;
}
}

View File

@ -0,0 +1,44 @@
#pragma once
#include "pico/stdlib.h"
#include <string>
#include "spi_drv.hpp"
namespace pimoroni {
class IPAddress {
//--------------------------------------------------
// Variables
//--------------------------------------------------
private:
union {
uint8_t bytes[WL_IPV4_LENGTH];
uint32_t dword;
} addr;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);
//--------------------------------------------------
// Operators
//--------------------------------------------------
public:
bool operator==(const IPAddress &address) const;
bool operator==(const uint32_t &address) const;
uint8_t operator[](int index) const;
uint8_t& operator[](int index);
IPAddress& operator=(uint32_t address);
operator uint32_t() const;
std::string to_string() const;
const uint8_t* to_bytes() const;
};
}

View File

@ -0,0 +1,314 @@
#include "spi_drv.hpp"
namespace pimoroni {
void SpiDrv::init() {
spi_init(spi, 8000000);
gpio_set_function(miso, GPIO_FUNC_SPI);
gpio_set_function(sck, GPIO_FUNC_SPI);
gpio_set_function(mosi, GPIO_FUNC_SPI);
// Chip select is active-low, so we'll initialise it to a driven-high state
gpio_init(cs);
gpio_set_dir(cs, GPIO_OUT);
gpio_put(cs, true);
gpio_init(gpio0);
gpio_set_dir(gpio0, GPIO_OUT);
gpio_init(resetn);
gpio_set_dir(resetn, GPIO_OUT);
}
void SpiDrv::reset() {
gpio_put(gpio0, true);
gpio_put(cs, true);
gpio_put(resetn, false);
sleep_ms(10);
gpio_put(resetn, true);
sleep_ms(750);
}
bool SpiDrv::available() {
return gpio_get(gpio0);
}
void SpiDrv::esp_select() {
gpio_put(cs, false);
}
void SpiDrv::esp_deselect() {
gpio_put(cs, true);
}
bool SpiDrv::get_esp_ready() {
return !gpio_get(ack);
}
bool SpiDrv::get_esp_ack() {
return gpio_get(ack);
}
void SpiDrv::wait_for_esp_ack() {
while(!get_esp_ack()) {
tight_loop_contents();
}
}
void SpiDrv::wait_for_esp_ready() {
while(!get_esp_ready()) {
tight_loop_contents();
}
}
void SpiDrv::wait_for_esp_select() {
wait_for_esp_ready();
esp_select();
wait_for_esp_ack();
}
int SpiDrv::wait_for_byte(uint8_t wait_byte) {
int timeout = BYTE_TIMEOUT;
uint8_t byte_read = 0;
do{
byte_read = read_byte(); //get data byte
if (byte_read == ERR_CMD) {
printf("Err cmd received\n");
return -1;
}
} while((timeout-- > 0) && (byte_read != wait_byte));
return (byte_read == wait_byte);
}
bool SpiDrv::read_and_check_byte(uint8_t check_byte, uint8_t *byte_out) {
get_param(byte_out);
return (*byte_out == check_byte);
}
uint8_t SpiDrv::read_byte() {
uint8_t byte_read = 0;
get_param(&byte_read);
return byte_read;
}
bool SpiDrv::wait_response_params(uint8_t cmd, uint8_t num_param, tParam *params_out) {
uint8_t data = 0;
int i = 0;
IF_CHECK_START_CMD() {
CHECK_DATA(cmd | REPLY_FLAG, data){};
uint8_t num_param_read = read_byte();
if(num_param_read != 0) {
for(i = 0; i < num_param_read; ++i) {
params_out[i].param_len = read_param_len8();
spi_read_blocking(spi, DUMMY_DATA, params_out[i].param, params_out[i].param_len);
}
}
else {
printf("Error num_param == 0\n");
return false;
}
if(num_param != num_param_read) {
printf("Mismatch num_param\n");
return false;
}
read_and_check_byte(END_CMD, &data);
}
return true;
}
bool SpiDrv::wait_response_cmd(uint8_t cmd, uint8_t num_param, uint8_t *param_out, uint8_t *param_len_out) {
uint8_t data = 0;
int ii = 0;
IF_CHECK_START_CMD() {
CHECK_DATA(cmd | REPLY_FLAG, data){};
CHECK_DATA(num_param, data) {
read_param_len8(param_len_out);
for(ii = 0; ii < (*param_len_out); ++ii) {
get_param(&param_out[ii]);
}
}
read_and_check_byte(END_CMD, &data);
}
return true;
}
bool SpiDrv::wait_response_data8(uint8_t cmd, uint8_t *param_out, uint8_t *param_len_out) {
uint8_t data = 0;
IF_CHECK_START_CMD() {
CHECK_DATA(cmd | REPLY_FLAG, data){};
uint8_t num_param_read = read_byte();
if(num_param_read != 0) {
read_param_len8(param_len_out);
spi_read_blocking(spi, DUMMY_DATA, param_out, *param_len_out);
}
read_and_check_byte(END_CMD, &data);
}
return true;
}
bool SpiDrv::wait_response_data16(uint8_t cmd, uint8_t* param_out, uint16_t *param_len_out) {
uint8_t data = 0;
IF_CHECK_START_CMD() {
CHECK_DATA(cmd | REPLY_FLAG, data){};
uint8_t num_param_read = read_byte();
if(num_param_read != 0) {
read_param_len16(param_len_out);
spi_read_blocking(spi, DUMMY_DATA, param_out, *param_len_out);
}
read_and_check_byte(END_CMD, &data);
}
return false;
}
bool SpiDrv::wait_response(uint8_t cmd, uint8_t *num_param_out, uint8_t **params_out, uint8_t max_num_params) {
uint8_t data = 0;
int i = 0;
uint8_t* index[WL_SSID_MAX_LENGTH];
for(i = 0 ; i < WL_NETWORKS_LIST_MAXNUM; i++)
index[i] = (uint8_t*)params_out + (WL_SSID_MAX_LENGTH * i);
IF_CHECK_START_CMD() {
CHECK_DATA(cmd | REPLY_FLAG, data){};
uint8_t num_param_read = read_byte();
if(num_param_read > max_num_params) {
num_param_read = max_num_params;
}
*num_param_out = num_param_read;
if(num_param_read != 0) {
for(i = 0; i < num_param_read; ++i) {
uint8_t param_len = read_param_len8();
spi_read_blocking(spi, DUMMY_DATA, index[i], param_len);
index[i][param_len] = 0;
}
}
else {
printf("Error numParams == 0\n");
read_and_check_byte(END_CMD, &data);
return false;
}
read_and_check_byte(END_CMD, &data);
}
return true;
}
void SpiDrv::send_param(const uint8_t *param, uint8_t param_len, lastParam last_param) {
send_param_len8(param_len);
spi_write_blocking(spi, param, param_len);
if(last_param) {
uint8_t buf = END_CMD;
spi_write_blocking(spi, &buf, 1);
}
}
void SpiDrv::send_param_len8(uint8_t param_len) {
spi_write_blocking(spi, &param_len, 1);
}
void SpiDrv::send_param_len16(uint16_t param_len) {
uint8_t buf[2];
buf[0] = (uint8_t)((param_len & 0xff00) >> 8);
buf[1] = (uint8_t)(param_len & 0xff);
spi_write_blocking(spi, buf, 2);
}
uint8_t SpiDrv::read_param_len8(uint8_t *param_len_out) {
uint8_t param_len;
get_param(&param_len);
if(param_len_out != nullptr) {
*param_len_out = param_len;
}
return param_len;
}
uint16_t SpiDrv::read_param_len16(uint16_t *param_len_out) {
uint8_t buf[2];
spi_read_blocking(spi, DUMMY_DATA, buf, 2);
uint16_t param_len = (buf[0] << 8) | (buf[1] & 0xff);
if(param_len_out != nullptr) {
*param_len_out = param_len;
}
return param_len;
}
void SpiDrv::send_buffer(const uint8_t* param, uint16_t param_len, lastParam last_param) {
send_param_len16(param_len);
spi_write_blocking(spi, param, param_len);
if(last_param) {
uint8_t buf = END_CMD;
spi_write_blocking(spi, &buf, 1);
}
}
void SpiDrv::send_param(uint16_t param, lastParam last_param) {
send_param_len8(2);
uint8_t buf[2];
buf[0] = (uint8_t)((param & 0xff00) >> 8);
buf[1] = (uint8_t)(param & 0xff);
spi_write_blocking(spi, buf, 2);
if(last_param) {
uint8_t buf = END_CMD;
spi_write_blocking(spi, &buf, 1);
}
}
void SpiDrv::send_byte_param(uint8_t param, lastParam last_param) {
send_param_len8(1);
spi_write_blocking(spi, &param, 1);
if(last_param) {
uint8_t buf = END_CMD;
spi_write_blocking(spi, &buf, 1);
}
}
void SpiDrv::send_cmd(uint8_t cmd, uint8_t num_param) {
uint8_t buf[3];
buf[0] = START_CMD;
buf[1] = cmd & ~(REPLY_FLAG);
buf[2] = num_param;
spi_write_blocking(spi, buf, 3);
if(num_param == 0) {
uint8_t buf = END_CMD;
spi_write_blocking(spi, &buf, 1);
}
}
void SpiDrv::pad_to_multiple_of_4(int command_size) {
while(command_size % 4) {
read_byte();
command_size++;
}
}
void SpiDrv::get_param(uint8_t* param_out) {
spi_read_blocking(spi, DUMMY_DATA, param_out, 1);
}
}

View File

@ -0,0 +1,171 @@
#pragma once
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
// Maximum size of a SSID
#define WL_SSID_MAX_LENGTH 32
// Length of passphrase. Valid lengths are 8-63.
#define WL_WPA_KEY_MAX_LENGTH 63
// Length of key in bytes. Valid values are 5 and 13.
#define WL_WEP_KEY_MAX_LENGTH 13
// Size of a MAC-address or BSSID
#define WL_MAC_ADDR_LENGTH 6
// Size of a IP address
#define WL_IPV4_LENGTH 4
// Maximum size of a SSID list
#define WL_NETWORKS_LIST_MAXNUM 10
#define IF_CHECK_START_CMD() \
if(!wait_for_byte(START_CMD)) { \
printf("Error waiting START_CMD\n"); \
return false; \
} \
else \
#define CHECK_DATA(check, x) \
if(!read_and_check_byte(check, &x)) { \
printf("Reply error\n"); \
return false; \
} \
else \
namespace pimoroni {
class SpiDrv {
//--------------------------------------------------
// Constants
//--------------------------------------------------
public:
static const uint8_t DEFAULT_CS_PIN = 7;
static const uint8_t DEFAULT_SCK_PIN = 18;
static const uint8_t DEFAULT_MOSI_PIN = 19;
static const uint8_t DEFAULT_MISO_PIN = 16;
static const uint8_t DEFAULT_RESETN_PIN = 11;
static const uint8_t DEFAULT_GPIO0_PIN = 2;
static const uint8_t DEFAULT_ACK_PIN = 10;
static const uint8_t DUMMY_DATA = 0xFF;
private:
static const uint8_t START_CMD = 0xE0;
static const uint8_t END_CMD = 0xEE;
static const uint8_t ERR_CMD = 0xEF;
static const uint8_t CMD_FLAG = 0;
static const uint8_t REPLY_FLAG = 1 << 7;
static const uint8_t DATA_FLAG = 0x40;
static const uint8_t CMD_POS = 1; // Position of Command OpCode on SPI stream
static const uint8_t PARAM_LEN_POS = 2; // Position of Param len on SPI stream
static const int BYTE_TIMEOUT = 1000;
//--------------------------------------------------
// Enums
//--------------------------------------------------
public:
enum numParams : uint8_t {
PARAM_NUMS_0 = 0,
PARAM_NUMS_1,
PARAM_NUMS_2,
PARAM_NUMS_3,
PARAM_NUMS_4,
PARAM_NUMS_5
};
enum lastParam : bool {
NO_LAST_PARAM = false,
LAST_PARAM = true,
};
//--------------------------------------------------
// Substructures
//--------------------------------------------------
public:
struct tParam {
uint8_t param_len;
uint8_t* param;
};
//--------------------------------------------------
// Variables
//--------------------------------------------------
private:
spi_inst_t *spi = spi0;
int8_t cs = DEFAULT_CS_PIN;
int8_t sck = DEFAULT_SCK_PIN;
int8_t mosi = DEFAULT_MOSI_PIN;
int8_t miso = DEFAULT_MISO_PIN;
int8_t resetn = DEFAULT_RESETN_PIN;
int8_t gpio0 = DEFAULT_GPIO0_PIN;
int8_t ack = DEFAULT_ACK_PIN;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
SpiDrv() {}
SpiDrv(spi_inst_t *spi,
uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t miso,
uint8_t resetn, uint8_t gpio0, uint8_t ack) :
spi(spi), cs(cs), sck(sck), mosi(mosi), miso(miso),
resetn(resetn), gpio0(gpio0), ack(ack) {}
//--------------------------------------------------
// Methods
//--------------------------------------------------
public:
void init();
void reset();
bool available();
void esp_select();
void esp_deselect();
bool get_esp_ready();
bool get_esp_ack();
void wait_for_esp_ack();
void wait_for_esp_ready();
void wait_for_esp_select();
int wait_for_byte(uint8_t wait_byte);
bool read_and_check_byte(uint8_t check_byte, uint8_t *byte_out);
uint8_t read_byte();
bool wait_response_params(uint8_t cmd, uint8_t num_param, tParam *params_out);
bool wait_response_cmd(uint8_t cmd, uint8_t num_param, uint8_t *param_out, uint8_t *param_len_out);
bool wait_response_data8(uint8_t cmd, uint8_t *param_out, uint8_t *param_len_out);
bool wait_response_data16(uint8_t cmd, uint8_t *param_out, uint16_t *param_len_out);
bool wait_response(uint8_t cmd, uint8_t *num_param_out, uint8_t **params_out, uint8_t max_num_params);
void send_param(const uint8_t* param, uint8_t param_len, lastParam last_param = NO_LAST_PARAM);
void send_param_len8(uint8_t param_len);
void send_param_len16(uint16_t param_len);
uint8_t read_param_len8(uint8_t *param_len_out = nullptr);
uint16_t read_param_len16(uint16_t *param_len_out = nullptr);
void send_buffer(const uint8_t *param, uint16_t param_len, lastParam last_param = NO_LAST_PARAM);
void send_param(uint16_t param, lastParam last_param = NO_LAST_PARAM);
void send_byte_param(uint8_t param, lastParam last_param = NO_LAST_PARAM);
void send_cmd(uint8_t cmd, uint8_t num_param);
void pad_to_multiple_of_4(int command_size);
private:
void get_param(uint8_t *param_out);
};
}

View File

@ -7,4 +7,5 @@ add_subdirectory(pico_explorer)
add_subdirectory(pico_rgb_keypad)
add_subdirectory(pico_rtc_display)
add_subdirectory(pico_tof_display)
add_subdirectory(pico_audio)
add_subdirectory(pico_audio)
add_subdirectory(pico_wireless)

1
examples/pico_wireless/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
secrets.h

View File

@ -0,0 +1,3 @@
include("${CMAKE_CURRENT_LIST_DIR}/demo.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/rgb_http.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cheerlights.cmake")

View File

@ -0,0 +1,14 @@
add_executable(
wireless_cheerlights
cheerlights.cpp
)
# enable usb output, disable uart output
pico_enable_stdio_usb(wireless_cheerlights 1)
pico_enable_stdio_uart(wireless_cheerlights 1)
# Pull in pico libraries that we need
target_link_libraries(wireless_cheerlights pico_stdlib pico_wireless)
# create map/bin/hex file etc.
pico_add_extra_outputs(wireless_cheerlights)

View File

@ -0,0 +1,258 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "pico_wireless.hpp"
#include "secrets.h"
#include <vector>
#include <algorithm>
#define HTTP_PORT 80
#define HTTP_REQUEST_BUF_SIZE 2048
#define DNS_CLOUDFLARE IPAddress(1, 1, 1, 1)
#define DNS_GOOGLE IPAddress(8, 8, 8, 8)
#define USE_DNS DNS_CLOUDFLARE
#define HTTP_REQUEST_DELAY 30 // Seconds between requests
#define HTTP_REQUEST_HOST "api.thingspeak.com"
#define HTTP_REQUEST_PATH "/channels/1417/field/2/last.txt"
#define HTTP_RESPONSE_BUF_SIZE 1024
using namespace pimoroni;
PicoWireless wireless;
uint8_t r, g, b;
uint8_t response_buf[HTTP_RESPONSE_BUF_SIZE];
typedef void(*http_handler)(unsigned int status_code, std::vector<std::string_view> response_head, std::vector<std::string_view> esponse_body);
enum HTTP_REQUEST_STATUS {
HTTP_REQUEST_OK = 0,
HTTP_REQUEST_TIMEOUT,
HTTP_REQUEST_RESPONSE_INVALID,
HTTP_REQUEST_RESPONSE_UNHANDLED,
HTTP_REQUEST_CONNECTION_FAILED,
HTTP_REQUEST_RESPONSE_OVERFLOW,
HTTP_REQUEST_NO_RESPONSE
};
std::vector<std::string_view> split(std::string_view str, std::string delim="\r\n") {
std::vector<std::string_view> result;
size_t offset = 0;
while (offset < str.size()) {
const auto pos = str.find_first_of(delim, offset);
// Emit an empty view even if two adjacent delimiters are found
// this ensurs the HTTP "blank line" start of content is found
result.emplace_back(str.substr(offset, pos - offset));
if (pos == std::string_view::npos) break;
offset = pos + delim.length();
}
return result;
}
uint32_t millis() {
return to_us_since_boot(get_absolute_time()) / 1000;
}
bool wifi_connect(std::string network, std::string password, IPAddress dns_server, uint32_t timeout=10000) {
printf("Connecting to %s...\n", network.c_str());
wireless.wifi_set_passphrase(network, password);
uint32_t t_start = millis();
while(millis() - t_start < timeout) {
if(wireless.get_connection_status() == WL_CONNECTED) {
printf("Connected!\n");
wireless.set_dns(1, dns_server, 0);
return true;
}
wireless.set_led(255, 0, 0);
sleep_ms(500);
wireless.set_led(0, 0, 0);
sleep_ms(500);
printf("...\n");
}
return false;
}
/* Basic function to connect to a client IP:PORT and poll for an established connection */
bool connect(IPAddress host_address, uint16_t port, uint8_t client_sock, uint32_t timeout = 1000) {
wireless.start_client(host_address, port, client_sock, TCP_MODE);
uint32_t t_start = millis();
while(millis() - t_start < timeout) {
uint8_t state = wireless.get_client_state(client_sock);
if(state == ESTABLISHED) return true;
sleep_ms(100);
}
return false;
}
/* Basic DNS lookup */
IPAddress dns_lookup(std::string request_host) {
IPAddress host_address(0, 0, 0, 0);
printf("DNS lookup for: %s\n", request_host.c_str());
if(!wireless.get_host_by_name(request_host.c_str(), host_address)) {
printf("DNS lookup failed!\n");
}
return host_address;
}
/* This is pretty much the simplest HTTP request function I could get away with.
It accepts a client socket ID, IP address, hostname, request path and handler function,
and calls the handler with the status code (only 200 & 404 at the moment), head
and body as `std::vector<std::string_view>` into the underlying buffer.
*/
HTTP_REQUEST_STATUS http_request(uint8_t client_sock, IPAddress host_address, uint16_t port, std::string request_host, std::string request_path, http_handler handler, uint32_t timeout = 1000) {
if(!connect(host_address, port, client_sock)) {
printf("Connection failed!\n");
return HTTP_REQUEST_CONNECTION_FAILED;
}
// HTTP request to grab our API endpoint
const std::string http_request = "GET " + request_path + " HTTP/1.1\r\n\
Host: " + request_host + "\r\n\
Connection: close\r\n\r\n";
// Clear the response buffer
memset(response_buf, 0, HTTP_RESPONSE_BUF_SIZE);
wireless.send_data(client_sock, (const uint8_t *)http_request.data(), http_request.length());
uint16_t response_length = 0;
uint16_t avail_length = 0;
uint32_t t_start = millis();
// Keep receiving data until our designated timeout
// There's no guarantee that `wireless.avail_data` will have the *whole* response in one shot
// and I *really* don't want to parse the HTTP response for a `Content-Length` header.
while(millis() - t_start < timeout) {
sleep_ms(50);
avail_length = wireless.avail_data(client_sock);
if(avail_length > 0) break;
}
// Read the full response
// Sometimes the bytes read is less than the bytes we request, so loop until we get the data we expect
while(response_length < avail_length) {
uint16_t read_length = avail_length; // Request the full buffer
wireless.get_data_buf(client_sock, response_buf + response_length, &read_length);
response_length += read_length; // Increment the response_length by the amount we actually read
// Also check for timeouts here, too
if(millis() - t_start >= timeout) break;
}
// Explicitly stop our client, and don't leave it dangling!
wireless.stop_client(client_sock);
// Bail if we timed out.
if(millis() - t_start >= timeout) return HTTP_REQUEST_TIMEOUT;
if(response_length > 0) {
std::vector<std::string_view> response = split(std::string_view((char *)response_buf, response_length));
std::vector<std::string_view> response_body;
uint32_t status_code = 0;
// Bail early on an invalid HTTP request
if(response[0].compare(0, 8, "HTTP/1.1") != 0) return HTTP_REQUEST_RESPONSE_INVALID;
// Scan for the blank line indicating content start
auto body_start = std::find(response.begin(), response.end(), "");
// Split the body from the head (ow!)
if(body_start != response.end()) {
response_body = std::vector<std::string_view>(body_start + 1, response.end());
response = std::vector<std::string_view>(response.begin(), body_start);
}
// Parse out the HTTP status code
status_code = std::stoul(std::string(response[0].substr(9, 12)), nullptr);
if(status_code != 0) {
handler(status_code, response, response_body);
return HTTP_REQUEST_OK;
}
return HTTP_REQUEST_RESPONSE_UNHANDLED;
}
return HTTP_REQUEST_NO_RESPONSE;
}
/* As above, but does DNS resolving for us, probably don't use this... */
int http_request(uint8_t client_sock, std::string request_host, uint16_t port, std::string request_path, http_handler handler, uint32_t timeout = 1000) {
IPAddress host_address = dns_lookup(request_host);
return http_request(client_sock, host_address, port, request_host, request_path, handler, timeout);
}
int main() {
stdio_init_all();
wireless.init();
sleep_ms(500);
printf("Firmware version Nina %s\n", wireless.get_fw_version());
if(!wifi_connect(NETWORK, PASSWORD, USE_DNS)) {
return 0;
}
g = 255;
wireless.set_led(r, g, b);
// Get a free client socket
uint8_t client_sock = wireless.get_socket();
// Be a good DNS citizen and cache our lookup
IPAddress host_address = dns_lookup(HTTP_REQUEST_HOST);
while(1) {
printf("Requesting: %s\n", HTTP_REQUEST_PATH);
HTTP_REQUEST_STATUS status = http_request(client_sock, host_address, HTTP_PORT, HTTP_REQUEST_HOST, HTTP_REQUEST_PATH, [](
unsigned int status_code,
std::vector<std::string_view> response_head,
std::vector<std::string_view> response_body) {
// Check for valid status
if(status_code != 200) return;
// Check for empty body
if(response_body.size() == 0) return;
// Check for our 7 chars "#000000"
if(response_body[0].length() != 7) return;
// Check for at least a *hopefully* valid hex colour
if(response_body[0].compare(0, 1, "#") != 0) return;
// Convert the hex colour to an unsigned int
uint32_t rgb = std::stoul(std::string(response_body[0].substr(1)), nullptr, 16);
// Unpack to RGB
r = (rgb >> 16) & 0xff;
g = (rgb >> 8) & 0xff;
b = (rgb >> 0) & 0xff;
printf("RGB: %i %i %i\n", r, g, b);
wireless.set_led(r, g, b);
});
if(status == HTTP_REQUEST_NO_RESPONSE) {
printf("No response :(\n");
}
if(status == HTTP_REQUEST_TIMEOUT) {
printf("Request timed out :(\n");
}
if(status == HTTP_REQUEST_RESPONSE_UNHANDLED) {
// Something unexpected happened!
}
sleep_ms(HTTP_REQUEST_DELAY * 1000); // Sensible delay
}
return 0;
}

View File

@ -0,0 +1,14 @@
add_executable(
wireless_time
demo.cpp
)
# enable usb output, disable uart output
pico_enable_stdio_usb(wireless_time 1)
pico_enable_stdio_uart(wireless_time 0)
# Pull in pico libraries that we need
target_link_libraries(wireless_time pico_stdlib pico_wireless)
# create map/bin/hex file etc.
pico_add_extra_outputs(wireless_time)

View File

@ -0,0 +1,127 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "pico_wireless.hpp"
#include <chrono>
#include <sstream>
#include <iomanip>
#include "secrets.h"
using namespace pimoroni;
#define UART_ID uart1 //uart0
#define BAUD_RATE 115200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
// We are using pins 0 and 1, but see the GPIO function select table in the
// datasheet for information on which other pins can be used.
#define UART_TX_PIN 8 //0
#define UART_RX_PIN 9 //1
// HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel
// Outputs are rgb in the range 0-255 for each channel
void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) {
float i = floor(h * 6.0f);
float f = h * 6.0f - i;
v *= 255.0f;
uint8_t p = v * (1.0f - s);
uint8_t q = v * (1.0f - f * s);
uint8_t t = v * (1.0f - (1.0f - f) * s);
switch (int(i) % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
}
PicoWireless wireless;
#define PICO_LED 25
int main() {
stdio_init_all();
//stdio_set_translate_crlf(&stdio_usb, false);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_init(UART_ID, BAUD_RATE);
gpio_put(PICO_LED, true);
printf("Initialised\n");
wireless.init();
sleep_ms(1000);
uint8_t r, g, b;
uint8_t a = 0;
while(!wireless.is_pressed(PicoWireless::A)) {
from_hsv((float)a/256.0f, 1, 1, r, g, b);
wireless.set_led(0, 0, b);
sleep_ms(10);
a++;
}
wireless.set_led(16, 16, 0);
printf("firmware version Nina %s\n", wireless.get_fw_version());
uint8_t* mac = wireless.get_mac_address();
printf("mac address ", wireless.get_mac_address()[0]);
for(uint i =0; i < WL_MAC_ADDR_LENGTH; i++) {
printf("%d:", mac[i]);
}
printf("\n");
printf("starting connection\n");
bool connected = wireless.wifi_set_passphrase(NETWORK, PASSWORD);
printf("waiting to establish connection status\n");
while(wireless.get_connection_status() != WL_CONNECTED) {
sleep_ms(1000);
printf("still waiting\n");
}
IPAddress ip;
wireless.get_ip_address(ip);
printf("ip address: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
IPAddress gateway;
wireless.get_gateway_ip(gateway);
printf("gateway address: %d.%d.%d.%d\n", gateway[0], gateway[1], gateway[2], gateway[3]);
printf("SSID = %s\n", wireless.get_current_ssid());
printf("RSSI = %d\n", wireless.get_current_rssi());
uint8_t t = 0;
while (true) {
from_hsv((float)t/256.0f, 1, 1, r, g, b);
wireless.set_led(r, g, b);
sleep_ms(10);
t++;
if(t == 0) {
//printf("time: %d, temp: %f\n", wireless.get_time(), wireless.get_temperature());
std::uint32_t time_date_stamp = wireless.get_time();
std::time_t temp = time_date_stamp;
std::tm* t = std::gmtime(&temp);
std::stringstream ss; // or if you're going to print, just input directly into the output stream
ss << std::put_time(t, "%Y-%m-%d %I:%M:%S %p\n");
std::string output = ss.str();
printf(output.c_str());
}
}
return 0;
}

View File

@ -0,0 +1,14 @@
add_executable(
wireless_rgb_http
rgb_http.cpp
)
# enable usb output, enable uart output
pico_enable_stdio_usb(wireless_rgb_http 1)
pico_enable_stdio_uart(wireless_rgb_http 1)
# Pull in pico libraries that we need
target_link_libraries(wireless_rgb_http pico_stdlib pico_wireless)
# create map/bin/hex file etc.
pico_add_extra_outputs(wireless_rgb_http)

View File

@ -0,0 +1,244 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "pico_wireless.hpp"
#include "secrets.h"
#include <vector>
#include <algorithm>
#define HTTP_PORT 80
#define HTTP_REQUEST_BUF_SIZE 2048
#define DNS_CLOUDFLARE IPAddress(1, 1, 1, 1)
#define DNS_GOOGLE IPAddress(8, 8, 8, 8)
#define USE_DNS DNS_CLOUDFLARE
using namespace pimoroni;
PicoWireless wireless;
uint8_t r, g, b;
uint8_t request_buf[HTTP_REQUEST_BUF_SIZE];
const std::string response_501 = "HTTP/1.1 501 Not Implemented\nContent-Length: 19\n\n501 Not Implemented";
enum http_request_method_t {
GET,
POST
};
typedef std::string_view(*http_request_handler)(http_request_method_t method, std::string_view path, std::vector<std::string_view> request_head, std::vector<std::string_view> request_body);
std::vector<std::string_view> split(std::string_view str, std::string delim="\r\n") {
std::vector<std::string_view> result;
size_t offset = 0;
while (offset < str.size()) {
const auto pos = str.find_first_of(delim, offset);
// Emit an empty view even if two adjacent delimiters are found
// this ensurs the HTTP "blank line" start of content is found
result.emplace_back(str.substr(offset, pos - offset));
if (pos == std::string_view::npos) break;
offset = pos + delim.length();
}
return result;
}
uint32_t millis() {
return to_us_since_boot(get_absolute_time()) / 1000;
}
bool wifi_connect(std::string network, std::string password, IPAddress dns_server, uint32_t timeout=10000) {
printf("Connecting to %s...\n", network.c_str());
wireless.wifi_set_passphrase(network, password);
uint32_t t_start = millis();
while(millis() - t_start < timeout) {
if(wireless.get_connection_status() == WL_CONNECTED) {
printf("Connected!\n");
wireless.set_dns(1, dns_server, 0);
return true;
}
wireless.set_led(255, 0, 0);
sleep_ms(500);
wireless.set_led(0, 0, 0);
sleep_ms(500);
printf("...\n");
}
return false;
}
int socket_accept(int8_t server_sock) {
uint8_t new_sock = wireless.avail_server(server_sock);
if(new_sock != server_sock
&& new_sock != 255) {
return new_sock;
}
return -1;
}
uint8_t start_server(uint16_t http_port) {
printf("Starting server...\n", NETWORK);
// Get a socket for our server
uint8_t server_sock = wireless.get_socket();
wireless.start_server(http_port, server_sock);
while(1){
uint8_t state = wireless.get_server_state(server_sock);
if(state == LISTEN) break;
}
IPAddress ip;
wireless.get_ip_address(ip);
printf("Server listening on %s:%i\n", ip.to_string().c_str(), http_port);
return server_sock;
}
bool poll_http_requests(uint8_t server_sock, http_request_handler request_handler, uint32_t timeout = 1000) {
uint16_t request_length = 0;
uint16_t avail_length = 0;
uint32_t t_start = millis();
// Clear the request buffer
memset(request_buf, 0, HTTP_REQUEST_BUF_SIZE);
// Try to accept an incoming connection
int client_sock = socket_accept(server_sock);
if(client_sock == -1) return false;
printf("Got client: %d\n", client_sock);
// Any data? This *usually* seems to be available immediately,
// so we can dispense with any ongoing polling and hope for the best.
avail_length = wireless.avail_data(client_sock);
if(avail_length == 0) return false;
printf("Got request: %i bytes\n", avail_length);
// Read the full response
// Sometimes the bytes read is less than the bytes we request, so loop until we get the data we expect
while(request_length < avail_length) {
uint16_t read_length = avail_length; // Request the full buffer
wireless.get_data_buf(client_sock, request_buf + request_length, &read_length);
request_length += read_length; // Increment the response_length by the amount we actually read
// Also check for timeouts here, too
if(millis() - t_start >= timeout) break;
}
// Bail if we timed out.
if(millis() - t_start >= timeout) {
wireless.stop_client(client_sock);
};
if(request_length > 0) {
std::vector<std::string_view> request = split(std::string_view((char *)request_buf, request_length));
std::vector<std::string_view> request_body;
std::vector<std::string_view> request_detail = split(request[0], " ");
http_request_method_t method;
// Bail early on an invalid HTTP request
if(request_detail[0].compare("POST") == 0) {
method = POST;
} else if (request_detail[0].compare("GET") == 0) {
method = GET;
} else { // PUT, DELETE, HEAD?
// Return a 501 unimplemented
wireless.send_data(client_sock, (const uint8_t *)response_501.data(), response_501.length());
wireless.stop_client(client_sock);
return false;
}
// Get the request path so we can handle routes
std::string_view path = request_detail[1];
// Scan for the blank line indicating content start for form post data
auto body_start = std::find(request.begin(), request.end(), "");
// Split the body from the head (ow!)
if(body_start != request.end()) {
request_body = std::vector<std::string_view>(body_start + 1, request.end());
request = std::vector<std::string_view>(request.begin(), body_start);
}
std::string_view response_body = request_handler(method, path, request, request_body);
std::string response_head = "HTTP/1.1 200 OK\nContent-Length: " + std::to_string(response_body.length()) + "\nContent-Type: text/html\n\n";
wireless.send_data(client_sock, (const uint8_t *)response_head.data(), response_head.length());
wireless.send_data(client_sock, (const uint8_t *)response_body.data(), response_body.length());
wireless.stop_client(client_sock);
return true;
}
return false;
}
int main() {
stdio_init_all();
wireless.init();
sleep_ms(500);
printf("Firmware version Nina %s\n", wireless.get_fw_version());
if(!wifi_connect(NETWORK, PASSWORD, USE_DNS)) {
return 0;
}
uint8_t server_sock = start_server(HTTP_PORT);
g = 255;
wireless.set_led(r, g, b);
while(1) {
// Handle any incoming HTTP requests
poll_http_requests(server_sock, [](
http_request_method_t request_method,
std::string_view request_path,
std::vector<std::string_view> request_head,
std::vector<std::string_view> request_body) -> std::string_view {
if(request_method == POST) {
// Split the URL-encoded POST data and parse the RGB values
std::vector<std::string_view> post_data = split(request_body[0], "&");
for(auto &data : post_data) {
// Must be at least 3 chars for "x=y"
if(data.length() < 3) continue;
// Must be in the form "x=y"
if(data[1] != '=') continue;
// "v" will be 0 on a parse failure, which isn't so bad.
int v = atoi((const char *)(data.data() + 2));
switch(data[0]) {
case 'r':
r = v;
printf("Got R: %i\n", r);
break;
case 'g':
g = v;
printf("Got G: %i\n", g);
break;
case 'b':
b = v;
printf("Got B: %i\n", b);
break;
}
wireless.set_led(r, g, b);
}
} else { // GET
if(request_path.compare("/hello") == 0) {
return "Hello World!";
}
}
return "\
<form method=\"post\" action=\"/\">\
<input id=\"r\" name=\"r\" type=\"number\" value=\"" + std::to_string(r) + "\" />\
<input name=\"g\" type=\"number\" value=\"" + std::to_string(g) + "\" />\
<input name=\"b\" type=\"number\" value=\"" + std::to_string(b) + "\" />\
<input type=\"submit\" value=\"Set LED\" />\
</form>";
});
sleep_ms(10);
}
return 0;
}

View File

@ -0,0 +1,7 @@
#include "pico/stdlib.h"
//DO NOT COMMIT THIS FILE!!!
//Your wireless network's name and password
#define NETWORK "network name here"
#define PASSWORD "network password here"

View File

@ -4,4 +4,5 @@ add_subdirectory(pico_display)
add_subdirectory(pico_unicorn)
add_subdirectory(pico_scroll)
add_subdirectory(pico_explorer)
add_subdirectory(pico_rgb_keypad)
add_subdirectory(pico_rgb_keypad)
add_subdirectory(pico_wireless)

View File

@ -0,0 +1,10 @@
add_library(pico_wireless INTERFACE)
target_sources(pico_wireless INTERFACE
${CMAKE_CURRENT_LIST_DIR}/pico_wireless.cpp
)
target_include_directories(pico_wireless INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(pico_wireless INTERFACE pico_stdlib hardware_spi esp32spi)

View File

@ -0,0 +1,11 @@
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/esp32wireless/esp32wireless.cmake)
add_library(pico_wireless INTERFACE)
target_sources(pico_wireless INTERFACE
${CMAKE_CURRENT_LIST_DIR}/pico_wireless.cpp
)
target_include_directories(pico_wireless INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(pico_wireless INTERFACE pico_stdlib hardware_spi esp32spi)

View File

@ -0,0 +1,35 @@
#include "pico_wireless.hpp"
#include "../../drivers/esp32spi/spi_drv.hpp"
namespace pimoroni {
bool PicoWireless::init() {
bool success = parent::init();
// setup button input
gpio_init(A);
gpio_set_dir(A, GPIO_IN);
gpio_pull_up(A);
set_led(0, 0, 0);
pin_mode(ESP_SD_DETECT, Esp32Spi::INPUT_PULLUP);
return success;
}
void PicoWireless::set_led(uint8_t r, uint8_t g, uint8_t b) {
analog_write(ESP_LED_R, 255 - r);
analog_write(ESP_LED_G, 255 - g);
analog_write(ESP_LED_B, 255 - b);
}
bool PicoWireless::is_pressed(uint8_t button) {
return !gpio_get(button);
}
bool PicoWireless::is_sdcard_detected() {
return digital_read(ESP_SD_DETECT);
}
}

View File

@ -0,0 +1,45 @@
#pragma once
#include "pico/stdlib.h"
#include "../../drivers/esp32spi/esp32spi.hpp"
namespace pimoroni {
class PicoWireless : public Esp32Spi {
typedef Esp32Spi parent;
//--------------------------------------------------
// Constants
//--------------------------------------------------
public:
static const uint8_t A = 12;
static const uint8_t ESP_LED_R = 25;
static const uint8_t ESP_LED_G = 26;
static const uint8_t ESP_LED_B = 27;
static const uint8_t ESP_SD_DETECT = 15;
//--------------------------------------------------
// Variables
//--------------------------------------------------
private:
public:
//PicoWireless();
//--------------------------------------------------
// Methods
//--------------------------------------------------
public:
virtual bool init();
void set_led(uint8_t r, uint8_t g, uint8_t b);
bool is_pressed(uint8_t button);
bool is_sdcard_detected();
};
}

View File

@ -0,0 +1,112 @@
import time
import picowireless
from micropython import const
WIFI_SSID = "your SSID here!"
WIFI_PASS = "Your PSK here!"
CLOUDFLARE_DNS = (1, 1, 1, 1)
GOOGLE_DNS = (8, 8, 8, 8)
USE_DNS = CLOUDFLARE_DNS
TCP_MODE = const(0)
HTTP_REQUEST_DELAY = const(30)
HTTP_PORT = 80
HTTP_REQUEST_HOST = "api.thingspeak.com"
HTTP_REQUEST_PATH = "/channels/1417/field/2/last.txt"
def connect(host_address, port, client_sock, timeout=1000):
picowireless.client_start(host_address, port, client_sock, TCP_MODE)
t_start = time.time()
timeout /= 1000.0
while time.time() - t_start < timeout:
state = picowireless.get_client_state(client_sock)
if state == 4:
return True
time.sleep(1.0)
return False
def http_request(client_sock, host_address, port, request_host, request_path, handler):
print("Connecting to {1}.{2}.{3}.{4}:{0}...".format(port, *host_address))
if not connect(host_address, port, client_sock):
print("Connection failed!")
return False
print("Connected!")
http_request = """GET {} HTTP/1.1
Host: {}
Connection: close
""".format(request_path, request_host).replace("\n", "\r\n")
picowireless.send_data(client_sock, http_request)
while True:
avail_length = picowireless.avail_data(client_sock)
if avail_length > 0:
break
print("Got response: {} bytes".format(avail_length))
response = b""
while len(response) < avail_length:
data = picowireless.get_data_buf(client_sock)
response += data
response = response.decode("utf-8")
head, body = response.split("\r\n\r\n", 1)
dhead = {}
for line in head.split("\r\n")[1:]:
key, value = line.split(": ", 1)
dhead[key] = value
handler(dhead, body)
picowireless.client_stop(client_sock)
picowireless.init()
print("Connecting to {}...".format(WIFI_SSID))
picowireless.wifi_set_passphrase(WIFI_SSID, WIFI_PASS)
while True:
if picowireless.get_connection_status() == 3:
break
print("Connected!")
# Get our own local IP!
my_ip = picowireless.get_ip_address()
print("Local IP: {}.{}.{}.{}".format(*my_ip))
# Resolve and cache the IP address
picowireless.set_dns(USE_DNS)
http_address = picowireless.get_host_by_name(HTTP_REQUEST_HOST)
print("Resolved {} to {}.{}.{}.{}".format(HTTP_REQUEST_HOST, *http_address))
client_sock = picowireless.get_socket()
def handler(head, body):
if head["Status"] == "200 OK":
color = body[1:]
r = int(color[0:2], 16)
g = int(color[3:4], 16)
b = int(color[5:6], 16)
picowireless.set_led(r, g, b)
print("Set LED to {} {} {}".format(r, g, b))
else:
print("Error: {}".format(head["Status"]))
while True:
http_request(client_sock, http_address, HTTP_PORT, HTTP_REQUEST_HOST, HTTP_REQUEST_PATH, handler)
time.sleep(60.0)

View File

@ -0,0 +1,182 @@
import time
import picowireless
from micropython import const
WIFI_SSID = "your SSID here!"
WIFI_PASS = "Your PSK here!"
TCP_CLOSED = 0
TCP_LISTEN = 1
CLOUDFLARE_DNS = (1, 1, 1, 1)
GOOGLE_DNS = (8, 8, 8, 8)
TCP_MODE = const(0)
HTTP_REQUEST_DELAY = const(30)
HTTP_PORT = 80
routes = {}
r = 0
g = 0
b = 0
def start_wifi():
picowireless.init()
print("Connecting to {}...".format(WIFI_SSID))
picowireless.wifi_set_passphrase(WIFI_SSID, WIFI_PASS)
while True:
if picowireless.get_connection_status() == 3:
break
print("Connected!")
def start_server(http_port, timeout=1.0):
my_ip = picowireless.get_ip_address()
print("Starting server...")
server_sock = picowireless.get_socket()
picowireless.server_start(http_port, server_sock, 0)
t_start = time.time()
while time.time() - t_start < timeout:
state = picowireless.get_server_state(server_sock)
if state == TCP_LISTEN:
print("Server listening on {1}.{2}.{3}.{4}:{0}".format(http_port, *my_ip))
return server_sock
return None
def handle_http_request(server_sock, timeout=1.0):
t_start = time.time()
client_sock = picowireless.avail_server(server_sock)
if client_sock in [server_sock, 255, -1]:
return False
print("Client connected!")
avail_length = picowireless.avail_data(client_sock)
if avail_length == 0:
picowireless.client_stop(client_sock)
return False
request = b""
while len(request) < avail_length:
data = picowireless.get_data_buf(client_sock)
request += data
if time.time() - t_start > timeout:
print("Client timed out getting data!")
picowireless.client_stop(client_sock)
return False
request = request.decode("utf-8")
if len(request) > 0:
head, body = request.split("\r\n\r\n", 1)
dhead = {}
for line in head.split("\r\n")[1:]:
key, value = line.split(": ", 1)
dhead[key] = value
method, url, _ = head.split("\r\n", 1)[0].split(" ")
print("Serving {} on {}...".format(method, url))
response = None
# Dispatch the request to the relevant route
if url in routes and method in routes[url] and callable(routes[url][method]):
if method == "POST":
data = {}
for var in body.split("&"):
key, value = var.split("=")
data[key] = value
response = routes[url][method](method, url, data)
else:
response = routes[url][method](method, url)
if response is not None:
response = "HTTP/1.1 200 OK\r\nContent-Length: {}\r\nContent-Type: text/html\r\n\r\n".format(len(response)) + response
picowireless.send_data(client_sock, response)
picowireless.client_stop(client_sock)
print("Success! Sending 200 OK")
return True
else:
picowireless.send_data(client_sock, "HTTP/1.1 501 Not Implemented\r\nContent-Length: 19\r\n\r\n501 Not Implemented")
picowireless.client_stop(client_sock)
print("Unhandled Request! Sending 501 OK")
return False
def route(url, methods="GET"):
if type(methods) is str:
methods = [methods]
def decorate(handler):
for method in methods:
if url not in routes:
routes[url] = {}
routes[url][method] = handler
return decorate
# Edit your routes here
# Nothing fancy is supported, just plain ol' URLs and GET/POST methods
@route("/", methods=["GET", "POST"])
def get_home(method, url, data=None):
if method == "POST":
global r, g, b
r = int(data.get("r", 0))
g = int(data.get("g", 0))
b = int(data.get("b", 0))
picowireless.set_led(r, g, b)
print("Set LED to {} {} {}".format(r, g, b))
return """<form method="post" action="/">
<input id="r" name="r" type="number" value="{r}" />
<input name="g" type="number" value="{g}" />
<input name="b" type="number" value="{b}" />
<input type="submit" value="Set LED" />
</form>""".format(r=r, g=g, b=b)
@route("/test", methods="GET")
def get_test(method, url):
return "Hello World!"
start_wifi()
server_sock = start_server(HTTP_PORT)
while True:
handle_http_request(server_sock)
time.sleep(0.01)
# Whoa there! Did you know you could run the server polling loop
# on Pico's *other* core!? Here's how:
#
# import _thread
#
# def server_loop_forever():
# # Start a server and continuously poll for HTTP requests
# server_sock = start_server(HTTP_PORT)
# while True:
# handle_http_request(server_sock)
# time.sleep(0.01)
#
# Handle the server polling loop on the other core!
# _thread.start_new_thread(server_loop_forever, ())
#
# # Your very own main loop for fun and profit!
# while True:
# print("Colour: {} {} {}".format(r, g, b))
# time.sleep(5.0)

View File

@ -4,4 +4,5 @@ include(${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/pico_unicorn/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/pico_display/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/pico_explorer/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/pico_wireless/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ulab/code/micropython.cmake)

View File

@ -0,0 +1,28 @@
set(MOD_NAME pico_wireless)
string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER)
add_library(usermod_${MOD_NAME} INTERFACE)
target_sources(usermod_${MOD_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/${MOD_NAME}/${MOD_NAME}.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/esp32spi/esp32spi.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/esp32spi/spi_drv.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/esp32spi/ip_address.cpp
)
target_include_directories(usermod_${MOD_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
target_compile_definitions(usermod_${MOD_NAME} INTERFACE
-DMODULE_${MOD_NAME_UPPER}_ENABLED=1
)
target_link_libraries(usermod INTERFACE usermod_${MOD_NAME})
set_source_files_properties(
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
PROPERTIES COMPILE_FLAGS
"-Wno-discarded-qualifiers -Wno-implicit-int"
)

View File

@ -0,0 +1,12 @@
WIRELESS_MOD_DIR := $(USERMOD_DIR)
# Add our source files to the respective variables.
SRC_USERMOD += $(WIRELESS_MOD_DIR)/esp32spi.c
SRC_USERMOD_CXX += $(WIRELESS_MOD_DIR)/esp32spi.cpp
# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(WIRELESS_MOD_DIR)
CXXFLAGS_USERMOD += -I$(WIRELESS_MOD_DIR)
# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++

View File

@ -0,0 +1,182 @@
#include "pico_wireless.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// picowireless Module
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Module Functions *****/
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_init_obj, picowireless_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_network_data_obj, picowireless_get_network_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_remote_data_obj, 1, picowireless_get_remote_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_network_obj, 1, picowireless_wifi_set_network);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_passphrase_obj, 2, picowireless_wifi_set_passphrase);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_key_obj, 3, picowireless_wifi_set_key);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_config_obj, 4, picowireless_config);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_set_dns_obj, 1, picowireless_set_dns);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_set_hostname_obj, 1, picowireless_set_hostname);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_disconnect_obj, picowireless_disconnect);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_connection_status_obj, picowireless_get_connection_status);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_mac_address_obj, picowireless_get_mac_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_ip_address_obj, picowireless_get_ip_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_subnet_mask_obj, picowireless_get_subnet_mask);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_gateway_ip_obj, picowireless_get_gateway_ip);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_current_ssid_obj, picowireless_get_current_ssid);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_current_bssid_obj, picowireless_get_current_bssid);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_current_rssi_obj, picowireless_get_current_rssi);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_current_encryption_type_obj, picowireless_get_current_encryption_type);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_start_scan_networks_obj, picowireless_start_scan_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_scan_networks_obj, picowireless_get_scan_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_ssid_networks_obj, 1, picowireless_get_ssid_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_enc_type_networks_obj, 1, picowireless_get_enc_type_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_bssid_networks_obj, 1, picowireless_get_bssid_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_channel_networks_obj, 1, picowireless_get_channel_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_rssi_networks_obj, 1, picowireless_get_rssi_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_req_host_by_name_obj, 1, picowireless_req_host_by_name);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_host_by_name_obj, 0, picowireless_get_host_by_name);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_fw_version_obj, picowireless_get_fw_version);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_time_obj, picowireless_get_time);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_set_power_mode_obj, 1, picowireless_set_power_mode);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_ap_network_obj, 2, picowireless_wifi_set_ap_network);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_ap_passphrase_obj, 3, picowireless_wifi_set_ap_passphrase);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_ping_obj, 2, picowireless_ping);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_debug_obj, 1, picowireless_debug);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_temperature_obj, picowireless_get_temperature);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_pin_mode_obj, 2, picowireless_pin_mode);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_digital_write_obj, 2, picowireless_digital_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_analog_write_obj, 2, picowireless_analog_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_digital_read_obj, 1, picowireless_digital_read);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_analog_read_obj, 1, picowireless_analog_read);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_server_start_obj, 3, picowireless_server_start);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_client_start_obj, 4, picowireless_client_start);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_client_stop_obj, 1, picowireless_client_stop);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_server_state_obj, 1, picowireless_get_server_state);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_client_state_obj, 1, picowireless_get_client_state);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_avail_data_obj, 1, picowireless_avail_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_avail_server_obj, 1, picowireless_avail_server);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_data_obj, 2, picowireless_get_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_get_data_buf_obj, 1, picowireless_get_data_buf);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_insert_data_buf_obj, 2, picowireless_insert_data_buf);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_send_udp_data_obj, 1, picowireless_send_udp_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_send_data_obj, 2, picowireless_send_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_check_data_sent_obj, 1, picowireless_check_data_sent);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_get_socket_obj, picowireless_get_socket);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_ent_identity_obj, 1, picowireless_wifi_set_ent_identity);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_ent_username_obj, 1, picowireless_wifi_set_ent_username);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_wifi_set_ent_password_obj, 1, picowireless_wifi_set_ent_password);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_wifi_set_ent_enable_obj, picowireless_wifi_set_ent_enable);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(picowireless_set_led_obj, 3, picowireless_set_led);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_is_pressed_obj, picowireless_is_pressed);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picowireless_is_sdcard_detected_obj, picowireless_is_sdcard_detected);
/***** Globals Table *****/
STATIC const mp_map_elem_t picowireless_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picowireless) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picowireless_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_network_data), MP_ROM_PTR(&picowireless_get_network_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_remote_data), MP_ROM_PTR(&picowireless_get_remote_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_network), MP_ROM_PTR(&picowireless_wifi_set_network_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_passphrase), MP_ROM_PTR(&picowireless_wifi_set_passphrase_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_key), MP_ROM_PTR(&picowireless_wifi_set_key_obj) },
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&picowireless_config_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_dns), MP_ROM_PTR(&picowireless_set_dns_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_hostname), MP_ROM_PTR(&picowireless_set_hostname_obj) },
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&picowireless_disconnect_obj) }
,
{ MP_ROM_QSTR(MP_QSTR_get_connection_status), MP_ROM_PTR(&picowireless_get_connection_status_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_mac_address), MP_ROM_PTR(&picowireless_get_mac_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_ip_address), MP_ROM_PTR(&picowireless_get_ip_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_subnet_mask), MP_ROM_PTR(&picowireless_get_subnet_mask_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_gateway_ip), MP_ROM_PTR(&picowireless_get_gateway_ip_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_current_ssid), MP_ROM_PTR(&picowireless_get_current_ssid_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_current_bssid), MP_ROM_PTR(&picowireless_get_current_bssid_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_current_rssi), MP_ROM_PTR(&picowireless_get_current_rssi_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_current_encryption_type), MP_ROM_PTR(&picowireless_get_current_encryption_type_obj) },
{ MP_ROM_QSTR(MP_QSTR_start_scan_networks), MP_ROM_PTR(&picowireless_start_scan_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_scan_networks), MP_ROM_PTR(&picowireless_get_scan_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_ssid_networks), MP_ROM_PTR(&picowireless_get_ssid_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_enc_type_networks), MP_ROM_PTR(&picowireless_get_enc_type_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_bssid_networks), MP_ROM_PTR(&picowireless_get_bssid_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_channel_networks), MP_ROM_PTR(&picowireless_get_channel_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_rssi_networks), MP_ROM_PTR(&picowireless_get_rssi_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_req_host_by_name), MP_ROM_PTR(&picowireless_req_host_by_name_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_host_by_name), MP_ROM_PTR(&picowireless_get_host_by_name_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_fw_version), MP_ROM_PTR(&picowireless_get_fw_version_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_time), MP_ROM_PTR(&picowireless_get_time_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_power_mode), MP_ROM_PTR(&picowireless_set_power_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ap_network), MP_ROM_PTR(&picowireless_wifi_set_ap_network_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ap_passphrase), MP_ROM_PTR(&picowireless_wifi_set_ap_passphrase_obj) },
{ MP_ROM_QSTR(MP_QSTR_ping), MP_ROM_PTR(&picowireless_ping_obj) },
{ MP_ROM_QSTR(MP_QSTR_debug), MP_ROM_PTR(&picowireless_debug_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_temperature), MP_ROM_PTR(&picowireless_get_temperature_obj) },
{ MP_ROM_QSTR(MP_QSTR_pin_mode), MP_ROM_PTR(&picowireless_pin_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_digital_write), MP_ROM_PTR(&picowireless_digital_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_analog_write), MP_ROM_PTR(&picowireless_analog_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_digital_read), MP_ROM_PTR(&picowireless_digital_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_analog_read), MP_ROM_PTR(&picowireless_analog_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_server_start), MP_ROM_PTR(&picowireless_server_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_client_start), MP_ROM_PTR(&picowireless_client_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_client_stop), MP_ROM_PTR(&picowireless_client_stop_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_server_state), MP_ROM_PTR(&picowireless_get_server_state_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_client_state), MP_ROM_PTR(&picowireless_get_client_state_obj) },
{ MP_ROM_QSTR(MP_QSTR_avail_data), MP_ROM_PTR(&picowireless_avail_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_avail_server), MP_ROM_PTR(&picowireless_avail_server_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_data), MP_ROM_PTR(&picowireless_get_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_data_buf), MP_ROM_PTR(&picowireless_get_data_buf_obj) },
{ MP_ROM_QSTR(MP_QSTR_insert_data_buf), MP_ROM_PTR(&picowireless_insert_data_buf_obj) },
{ MP_ROM_QSTR(MP_QSTR_send_udp_data), MP_ROM_PTR(&picowireless_send_udp_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_send_data), MP_ROM_PTR(&picowireless_send_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_check_data_sent), MP_ROM_PTR(&picowireless_check_data_sent_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_socket), MP_ROM_PTR(&picowireless_get_socket_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ent_identity), MP_ROM_PTR(&picowireless_wifi_set_ent_identity_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ent_username), MP_ROM_PTR(&picowireless_wifi_set_ent_username_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ent_password), MP_ROM_PTR(&picowireless_wifi_set_ent_password_obj) },
{ MP_ROM_QSTR(MP_QSTR_wifi_set_ent_enable), MP_ROM_PTR(&picowireless_wifi_set_ent_enable_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_led), MP_ROM_PTR(&picowireless_set_led_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picowireless_is_pressed_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_sdcard_detected), MP_ROM_PTR(&picowireless_is_sdcard_detected_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_picowireless_globals, picowireless_globals_table);
/***** Module Definition *****/
const mp_obj_module_t picowireless_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_picowireless_globals,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
MP_REGISTER_MODULE(MP_QSTR_picowireless, picowireless_user_cmodule, MODULE_PICO_WIRELESS_ENABLED);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
// Include MicroPython API.
#include "py/runtime.h"
#include "py/objstr.h"
// Declare the functions we'll make available in Python
extern mp_obj_t picowireless_init();
extern mp_obj_t picowireless_get_network_data();
extern mp_obj_t picowireless_get_remote_data(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_network(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_passphrase(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_key(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_config(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_set_dns(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_set_hostname(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_disconnect();
extern mp_obj_t picowireless_get_connection_status();
extern mp_obj_t picowireless_get_mac_address();
extern mp_obj_t picowireless_get_ip_address();
extern mp_obj_t picowireless_get_subnet_mask();
extern mp_obj_t picowireless_get_gateway_ip();
extern mp_obj_t picowireless_get_current_ssid();
extern mp_obj_t picowireless_get_current_bssid();
extern mp_obj_t picowireless_get_current_rssi();
extern mp_obj_t picowireless_get_current_encryption_type();
extern mp_obj_t picowireless_start_scan_networks();
extern mp_obj_t picowireless_get_scan_networks();
extern mp_obj_t picowireless_get_ssid_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_enc_type_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_bssid_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_channel_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_rssi_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_req_host_by_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_host_by_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_fw_version();
extern mp_obj_t picowireless_get_time();
extern mp_obj_t picowireless_set_power_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_ap_network(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_ap_passphrase(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_debug(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_temperature();
extern mp_obj_t picowireless_pin_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_digital_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_analog_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_digital_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_analog_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_server_start(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_client_start(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_client_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_server_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_client_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_avail_data(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_avail_server(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_data(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_data_buf(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_insert_data_buf(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_send_udp_data(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_send_data(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_check_data_sent(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_get_socket();
extern mp_obj_t picowireless_wifi_set_ent_identity(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_ent_username(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_ent_password(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_wifi_set_ent_enable();
extern mp_obj_t picowireless_set_led(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t picowireless_is_pressed();
extern mp_obj_t picowireless_is_sdcard_detected();