Merge pull request #126 from pimoroni/pico-wireless
C++/MicroPython Support & Examples for Pico Wireless
This commit is contained in:
commit
7776536d83
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(esp32spi)
|
||||
add_subdirectory(st7789)
|
||||
add_subdirectory(msa301)
|
||||
add_subdirectory(rv3028)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(esp32spi.cmake)
|
|
@ -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
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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(¶m_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, ¶m_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(¶m_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, ¶m, 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
secrets.h
|
|
@ -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")
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
)
|
|
@ -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++
|
|
@ -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
|
@ -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();
|
Loading…
Reference in New Issue