Update IDF to 3.2-3276a13 and esptool.py to 2.5.0 (#1878)

* TX Flow Control and Code cleanup

* Use semaphore instead of delay

TX functionality is done.

* Use single buffer and empty queue on exit

* Fix compile issues because of LwIP code relocation

* Add temporary header to fix Azure not compiling

* Fix AsyncUDP early init

* AsyncUDP Multicast fixes

* Add source mac address and rework multicast

* Allow redefinition of default pins for Serials 1 and 2

* Update IDF to 3276a13

* Update esptool.py to 2.5.0

* Fix sketches

* Fix log level in BluetoothSetial
This commit is contained in:
Me No Dev 2018-09-21 08:39:36 +02:00 committed by GitHub
parent 4e96bffe0e
commit 96822d783f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
447 changed files with 37993 additions and 10849 deletions

View File

@ -3,8 +3,25 @@
#include <string.h>
#include <inttypes.h>
#include "pins_arduino.h"
#include "HardwareSerial.h"
#ifndef RX1
#define RX1 9
#endif
#ifndef TX1
#define TX1 10
#endif
#ifndef RX2
#define RX2 16
#endif
#ifndef TX2
#define TX2 17
#endif
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
HardwareSerial Serial(0);
HardwareSerial Serial1(1);
@ -27,12 +44,12 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
txPin = 1;
}
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
rxPin = 9;
txPin = 10;
rxPin = RX1;
txPin = TX1;
}
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
rxPin = 16;
txPin = 17;
rxPin = RX2;
txPin = TX2;
}
_uart = uartBegin(_uart_nr, baud, config, rxPin, txPin, 256, invert);
}

View File

@ -0,0 +1 @@
#include "lwip/apps/sntp.h"

View File

@ -79,38 +79,50 @@ int log_printf(const char *fmt, ...);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
#define log_v(format, ...) log_printf(ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
#define isr_log_v(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
#else
#define log_v(format, ...)
#define isr_log_v(format, ...)
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
#define log_d(format, ...) log_printf(ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
#define isr_log_d(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
#else
#define log_d(format, ...)
#define isr_log_d(format, ...)
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#define log_i(format, ...) log_printf(ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
#define isr_log_i(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
#else
#define log_i(format, ...)
#define isr_log_i(format, ...)
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
#define log_w(format, ...) log_printf(ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
#define isr_log_w(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
#else
#define log_w(format, ...)
#define isr_log_w(format, ...)
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
#define log_e(format, ...) log_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#else
#define log_e(format, ...)
#define isr_log_e(format, ...)
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_NONE
#define log_n(format, ...) log_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#define isr_log_n(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#else
#define log_n(format, ...)
#define isr_log_n(format, ...)
#endif
#include "esp_log.h"
@ -121,12 +133,22 @@ int log_printf(const char *fmt, ...);
#undef ESP_LOGI
#undef ESP_LOGD
#undef ESP_LOGV
#undef ESP_EARLY_LOGE
#undef ESP_EARLY_LOGW
#undef ESP_EARLY_LOGI
#undef ESP_EARLY_LOGD
#undef ESP_EARLY_LOGV
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__)
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__)
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__)
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__)
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__)
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__)
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__)
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__)
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__)
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__)
#endif
#ifdef __cplusplus

View File

@ -13,7 +13,7 @@
// limitations under the License.
#include "esp32-hal.h"
#include "apps/sntp/sntp.h"
#include "lwip/apps/sntp.h"
static void setTimeZone(long offset, int daylight)
{

View File

@ -8,6 +8,7 @@ extern "C" {
#include "lwip/igmp.h"
#include "lwip/ip_addr.h"
#include "lwip/mld6.h"
#include "lwip/prot/ethernet.h"
#include <esp_err.h>
#include <esp_wifi.h>
}
@ -15,7 +16,7 @@ extern "C" {
#include "lwip/priv/tcpip_priv.h"
typedef struct {
struct tcpip_api_call call;
struct tcpip_api_call_data call;
udp_pcb * pcb;
const ip_addr_t *addr;
uint16_t port;
@ -24,7 +25,7 @@ typedef struct {
err_t err;
} udp_api_call_t;
static err_t _udp_connect_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_connect_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_connect(msg->pcb, msg->addr, msg->port);
return msg->err;
@ -35,11 +36,11 @@ static err_t _udp_connect(struct udp_pcb *pcb, const ip_addr_t *addr, u16_t port
msg.pcb = pcb;
msg.addr = addr;
msg.port = port;
tcpip_api_call(_udp_connect_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_connect_api, (struct tcpip_api_call_data*)&msg);
return msg.err;
}
static err_t _udp_disconnect_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_disconnect_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = 0;
udp_disconnect(msg->pcb);
@ -49,10 +50,10 @@ static err_t _udp_disconnect_api(struct tcpip_api_call *api_call_msg){
static void _udp_disconnect(struct udp_pcb *pcb){
udp_api_call_t msg;
msg.pcb = pcb;
tcpip_api_call(_udp_disconnect_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_disconnect_api, (struct tcpip_api_call_data*)&msg);
}
static err_t _udp_remove_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_remove_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = 0;
udp_remove(msg->pcb);
@ -62,10 +63,10 @@ static err_t _udp_remove_api(struct tcpip_api_call *api_call_msg){
static void _udp_remove(struct udp_pcb *pcb){
udp_api_call_t msg;
msg.pcb = pcb;
tcpip_api_call(_udp_remove_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_remove_api, (struct tcpip_api_call_data*)&msg);
}
static err_t _udp_bind_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_bind_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_bind(msg->pcb, msg->addr, msg->port);
return msg->err;
@ -76,11 +77,11 @@ static err_t _udp_bind(struct udp_pcb *pcb, const ip_addr_t *addr, u16_t port){
msg.pcb = pcb;
msg.addr = addr;
msg.port = port;
tcpip_api_call(_udp_bind_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_bind_api, (struct tcpip_api_call_data*)&msg);
return msg.err;
}
static err_t _udp_sendto_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_sendto_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_sendto(msg->pcb, msg->pb, msg->addr, msg->port);
return msg->err;
@ -92,11 +93,11 @@ static err_t _udp_sendto(struct udp_pcb *pcb, struct pbuf *pb, const ip_addr_t *
msg.addr = addr;
msg.port = port;
msg.pb = pb;
tcpip_api_call(_udp_sendto_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_sendto_api, (struct tcpip_api_call_data*)&msg);
return msg.err;
}
static err_t _udp_sendto_if_api(struct tcpip_api_call *api_call_msg){
static err_t _udp_sendto_if_api(struct tcpip_api_call_data *api_call_msg){
udp_api_call_t * msg = (udp_api_call_t *)api_call_msg;
msg->err = udp_sendto_if(msg->pcb, msg->pb, msg->addr, msg->port, msg->netif);
return msg->err;
@ -109,7 +110,7 @@ static err_t _udp_sendto_if(struct udp_pcb *pcb, struct pbuf *pb, const ip_addr_
msg.port = port;
msg.pb = pb;
msg.netif = netif;
tcpip_api_call(_udp_sendto_if_api, (struct tcpip_api_call*)&msg);
tcpip_api_call(_udp_sendto_if_api, (struct tcpip_api_call_data*)&msg);
return msg.err;
}
@ -292,19 +293,23 @@ AsyncUDPPacket::AsyncUDPPacket(AsyncUDP *udp, pbuf *pb, const ip_addr_t *raddr,
_remoteIp.type = raddr->type;
_localIp.type = _remoteIp.type;
eth_hdr* eth = NULL;
udp_hdr* udphdr = reinterpret_cast<udp_hdr*>(_data - UDP_HLEN);
_localPort = ntohs(udphdr->dest);
_remotePort = ntohs(udphdr->src);
if (_remoteIp.type == IPADDR_TYPE_V4) {
eth = (eth_hdr *)(((uint8_t *)(pb->payload)) - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
struct ip_hdr * iphdr = (struct ip_hdr *)(((uint8_t *)(pb->payload)) - UDP_HLEN - IP_HLEN);
_localIp.u_addr.ip4.addr = iphdr->dest.addr;
_remoteIp.u_addr.ip4.addr = iphdr->src.addr;
} else {
eth = (eth_hdr *)(((uint8_t *)(pb->payload)) - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
struct ip6_hdr * ip6hdr = (struct ip6_hdr *)(((uint8_t *)(pb->payload)) - UDP_HLEN - IP6_HLEN);
memcpy(&_localIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
memcpy(&_remoteIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->src.addr, 16);
}
memcpy(_remoteMac, eth->src.addr, 6);
struct netif * netif = NULL;
void * nif = NULL;
@ -415,6 +420,11 @@ uint16_t AsyncUDPPacket::remotePort()
return _remotePort;
}
void AsyncUDPPacket::remoteMac(uint8_t * mac)
{
memcpy(mac, _remoteMac, 6);
}
bool AsyncUDPPacket::isIPv6()
{
return _localIp.type == IPADDR_TYPE_V6;
@ -452,16 +462,24 @@ size_t AsyncUDPPacket::send(AsyncUDPMessage &message)
return write(message.data(), message.length());
}
AsyncUDP::AsyncUDP()
{
bool AsyncUDP::_init(){
if(_pcb){
return true;
}
_pcb = udp_new();
_connected = false;
_handler = NULL;
if(!_pcb){
return;
return false;
}
//_lock = xSemaphoreCreateMutex();
udp_recv(_pcb, &_udp_recv, (void *) this);
return true;
}
AsyncUDP::AsyncUDP()
{
_pcb = NULL;
_connected = false;
_handler = NULL;
}
AsyncUDP::~AsyncUDP()
@ -483,8 +501,7 @@ void AsyncUDP::close()
_udp_disconnect(_pcb);
}
_connected = false;
_pcb->multicast_ip.type = IPADDR_TYPE_V4;
_pcb->multicast_ip.u_addr.ip4.addr = 0;
//todo: unjoin multicast group
}
UDP_MUTEX_UNLOCK();
}
@ -495,7 +512,7 @@ bool AsyncUDP::connect(const ip_addr_t *addr, uint16_t port)
log_e("failed to start task");
return false;
}
if(_pcb == NULL) {
if(!_init()) {
return false;
}
close();
@ -516,7 +533,7 @@ bool AsyncUDP::listen(const ip_addr_t *addr, uint16_t port)
log_e("failed to start task");
return false;
}
if(_pcb == NULL) {
if(!_init()) {
return false;
}
close();
@ -534,57 +551,53 @@ bool AsyncUDP::listen(const ip_addr_t *addr, uint16_t port)
return true;
}
static esp_err_t joinMulticastGroup(const ip_addr_t *addr, bool join, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX)
{
struct netif * netif = NULL;
if(tcpip_if < TCPIP_ADAPTER_IF_MAX){
void * nif = NULL;
esp_err_t err = tcpip_adapter_get_netif(tcpip_if, &nif);
if (err) {
return ESP_ERR_INVALID_ARG;
}
netif = (struct netif *)nif;
}
if (addr->type == IPADDR_TYPE_V4) {
if(join){
if (igmp_joingroup_netif(netif, (const ip4_addr *)&(addr->u_addr.ip4))) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (igmp_leavegroup_netif(netif, (const ip4_addr *)&(addr->u_addr.ip4))) {
return ESP_ERR_INVALID_STATE;
}
}
} else {
if(join){
if (mld6_joingroup_netif(netif, &(addr->u_addr.ip6))) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (mld6_leavegroup_netif(netif, &(addr->u_addr.ip6))) {
return ESP_ERR_INVALID_STATE;
}
}
}
return ESP_OK;
}
bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl, tcpip_adapter_if_t tcpip_if)
{
if(!ip_addr_ismulticast(addr)) {
return false;
}
ip_addr_t multicast_if_addr;
uint8_t mode;
if(esp_wifi_get_mode((wifi_mode_t*)&mode)){
mode = WIFI_MODE_NULL;
}
if(addr->type == IPADDR_TYPE_V6){
multicast_if_addr.type = IPADDR_TYPE_V6;
if((tcpip_if == TCPIP_ADAPTER_IF_STA && (mode & WIFI_MODE_STA))
|| (tcpip_if == TCPIP_ADAPTER_IF_AP && (mode & WIFI_MODE_AP))
|| (tcpip_if == TCPIP_ADAPTER_IF_ETH)) {
if(tcpip_adapter_get_ip6_linklocal(tcpip_if, &multicast_if_addr.u_addr.ip6)){
return false;
}
} else {
return false;
}
if (mld6_joingroup(&(multicast_if_addr.u_addr.ip6), &(addr->u_addr.ip6))) {
return false;
}
} else if(addr->type == IPADDR_TYPE_V4){
tcpip_adapter_ip_info_t ifIpInfo;
if((tcpip_if == TCPIP_ADAPTER_IF_STA && (mode & WIFI_MODE_STA))
|| (tcpip_if == TCPIP_ADAPTER_IF_AP && (mode & WIFI_MODE_AP))
|| (tcpip_if == TCPIP_ADAPTER_IF_ETH)) {
if(tcpip_adapter_get_ip_info(tcpip_if, &ifIpInfo)){
return false;
}
} else {
return false;
}
multicast_if_addr.type = IPADDR_TYPE_V4;
multicast_if_addr.u_addr.ip4.addr = ifIpInfo.ip.addr;
if (igmp_joingroup((const ip4_addr *)&multicast_if_addr.u_addr.ip4, (const ip4_addr *)&addr->u_addr.ip4)!= ERR_OK) {
return false;
}
} else {
if (joinMulticastGroup(addr, true, tcpip_if)!= ERR_OK) {
return false;
}
if(!listen(&multicast_if_addr, port)) {
if(!listen(NULL, port)) {
return false;
}
@ -592,9 +605,7 @@ bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl
_pcb->mcast_ttl = ttl;
_pcb->remote_port = port;
ip_addr_copy(_pcb->remote_ip, *addr);
if(addr->type == IPADDR_TYPE_V4){
ip_addr_copy(_pcb->multicast_ip, multicast_if_addr);
}
//ip_addr_copy(_pcb->remote_ip, ip_addr_any_type);
UDP_MUTEX_UNLOCK();
return true;
@ -604,7 +615,7 @@ size_t AsyncUDP::writeTo(const uint8_t * data, size_t len, const ip_addr_t * add
{
if(!_pcb) {
UDP_MUTEX_LOCK();
_pcb = udp_new_ip_type(addr->type);
_pcb = udp_new();
UDP_MUTEX_UNLOCK();
if(_pcb == NULL) {
return 0;
@ -619,7 +630,7 @@ size_t AsyncUDP::writeTo(const uint8_t * data, size_t len, const ip_addr_t * add
uint8_t* dst = reinterpret_cast<uint8_t*>(pbt->payload);
memcpy(dst, data, len);
UDP_MUTEX_LOCK();
if(tcpip_if != TCPIP_ADAPTER_IF_MAX){
if(tcpip_if < TCPIP_ADAPTER_IF_MAX){
void * nif = NULL;
tcpip_adapter_get_netif((tcpip_adapter_if_t)tcpip_if, &nif);
if(!nif){

View File

@ -53,6 +53,7 @@ protected:
uint16_t _localPort;
ip_addr_t _remoteIp;
uint16_t _remotePort;
uint8_t _remoteMac[6];
uint8_t *_data;
size_t _len;
size_t _index;
@ -74,6 +75,7 @@ public:
IPAddress remoteIP();
IPv6Address remoteIPv6();
uint16_t remotePort();
void remoteMac(uint8_t * mac);
size_t send(AsyncUDPMessage &message);
@ -95,6 +97,7 @@ protected:
bool _connected;
AuPacketHandlerFunction _handler;
bool _init();
void _recv(udp_pcb *upcb, pbuf *pb, const ip_addr_t *addr, uint16_t port, struct netif * netif);
public:
@ -109,9 +112,9 @@ public:
bool listen(const IPv6Address addr, uint16_t port);
bool listen(uint16_t port);
bool listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_STA);
bool listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_STA);
bool listenMulticast(const IPv6Address addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_STA);
bool listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);
bool listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);
bool listenMulticast(const IPv6Address addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX);
bool connect(const ip_addr_t *addr, uint16_t port);
bool connect(const IPAddress addr, uint16_t port);

View File

@ -40,11 +40,115 @@
#include "esp32-hal-log.h"
#endif
const char * _spp_server_name = "ESP32_SPP_SERVER";
const char * _spp_server_name = "ESP32SPP";
#define QUEUE_SIZE 256
#define RX_QUEUE_SIZE 512
#define TX_QUEUE_SIZE 32
static uint32_t _spp_client = 0;
static xQueueHandle _spp_queue = NULL;
static xQueueHandle _spp_rx_queue = NULL;
static xQueueHandle _spp_tx_queue = NULL;
static SemaphoreHandle_t _spp_tx_done = NULL;
static TaskHandle_t _spp_task_handle = NULL;
static EventGroupHandle_t _spp_event_group = NULL;
#define SPP_RUNNING 0x01
#define SPP_CONNECTED 0x02
#define SPP_CONGESTED 0x04
typedef struct {
size_t len;
uint8_t data[];
} spp_packet_t;
static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){
if(!data || !len){
log_w("No data provided");
return ESP_OK;
}
spp_packet_t * packet = (spp_packet_t*)malloc(sizeof(spp_packet_t) + len);
if(!packet){
log_e("SPP TX Packet Malloc Failed!");
return ESP_FAIL;
}
packet->len = len;
memcpy(packet->data, data, len);
if (xQueueSend(_spp_tx_queue, &packet, portMAX_DELAY) != pdPASS) {
log_e("SPP TX Queue Send Failed!");
free(packet);
return ESP_FAIL;
}
return ESP_OK;
}
const uint16_t SPP_TX_MAX = 330;
static uint8_t _spp_tx_buffer[SPP_TX_MAX];
static uint16_t _spp_tx_buffer_len = 0;
static bool _spp_send_buffer(){
if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, portMAX_DELAY) & SPP_CONGESTED)){
esp_err_t err = esp_spp_write(_spp_client, _spp_tx_buffer_len, _spp_tx_buffer);
if(err != ESP_OK){
log_e("SPP Write Failed! [0x%X]", err);
return false;
}
_spp_tx_buffer_len = 0;
if(xSemaphoreTake(_spp_tx_done, portMAX_DELAY) != pdTRUE){
log_e("SPP Ack Failed!");
return false;
}
return true;
}
return false;
}
static void _spp_tx_task(void * arg){
spp_packet_t *packet = NULL;
size_t len = 0, to_send = 0;
uint8_t * data = NULL;
for (;;) {
if(_spp_tx_queue && xQueueReceive(_spp_tx_queue, &packet, portMAX_DELAY) == pdTRUE && packet){
if(packet->len <= (SPP_TX_MAX - _spp_tx_buffer_len)){
memcpy(_spp_tx_buffer+_spp_tx_buffer_len, packet->data, packet->len);
_spp_tx_buffer_len+=packet->len;
free(packet);
packet = NULL;
if(SPP_TX_MAX == _spp_tx_buffer_len || uxQueueMessagesWaiting(_spp_tx_queue) == 0){
_spp_send_buffer();
}
} else {
len = packet->len;
data = packet->data;
to_send = SPP_TX_MAX - _spp_tx_buffer_len;
memcpy(_spp_tx_buffer+_spp_tx_buffer_len, data, to_send);
_spp_tx_buffer_len = SPP_TX_MAX;
data += to_send;
len -= to_send;
_spp_send_buffer();
while(len >= SPP_TX_MAX){
memcpy(_spp_tx_buffer, data, SPP_TX_MAX);
_spp_tx_buffer_len = SPP_TX_MAX;
data += SPP_TX_MAX;
len -= SPP_TX_MAX;
_spp_send_buffer();
}
if(len){
memcpy(_spp_tx_buffer, data, len);
_spp_tx_buffer_len += len;
free(packet);
packet = NULL;
if(uxQueueMessagesWaiting(_spp_tx_queue) == 0){
_spp_send_buffer();
}
}
}
} else {
log_e("Something went horribly wrong");
}
}
vTaskDelete(NULL);
_spp_task_handle = NULL;
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
@ -54,44 +158,66 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
log_i("ESP_SPP_INIT_EVT");
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name);
xEventGroupSetBits(_spp_event_group, SPP_RUNNING);
break;
case ESP_SPP_SRV_OPEN_EVT://Server connection open
_spp_client = param->open.handle;
xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
log_i("ESP_SPP_SRV_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT://Client connection closed
_spp_client = 0;
xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
log_i("ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_CONG_EVT://connection congestion status changed
if(param->cong.cong){
xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
} else {
xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
}
log_v("ESP_SPP_CONG_EVT: %s", param->cong.cong?"CONGESTED":"FREE");
break;
case ESP_SPP_WRITE_EVT://write operation completed
if(param->write.cong){
xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
}
xSemaphoreGive(_spp_tx_done);//we can try to send another packet
log_v("ESP_SPP_WRITE_EVT: %u %s", param->write.len, param->write.cong?"CONGESTED":"FREE");
break;
case ESP_SPP_DATA_IND_EVT://connection received data
log_v("ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
//esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); //for low level debug
//ets_printf("r:%u\n", param->data_ind.len);
if (_spp_rx_queue != NULL){
for (int i = 0; i < param->data_ind.len; i++){
if(xQueueSend(_spp_rx_queue, param->data_ind.data + i, (TickType_t)0) != pdTRUE){
log_e("RX Full! Discarding %u bytes", param->data_ind.len - i);
break;
}
}
}
break;
//should maybe delete those.
case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete
log_i("ESP_SPP_DISCOVERY_COMP_EVT");
break;
case ESP_SPP_OPEN_EVT://Client connection open
log_i("ESP_SPP_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT://Client connection closed
_spp_client = 0;
log_i("ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_START_EVT://server started
log_i("ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT://client initiated a connection
log_i("ESP_SPP_CL_INIT_EVT");
break;
case ESP_SPP_DATA_IND_EVT://connection received data
log_v("ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
//esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); //for low level debug
if (_spp_queue != NULL){
for (int i = 0; i < param->data_ind.len; i++)
xQueueSend(_spp_queue, param->data_ind.data + i, (TickType_t)0);
} else {
log_e("SerialQueueBT ERROR");
}
break;
case ESP_SPP_CONG_EVT://connection congestion status changed
log_i("ESP_SPP_CONG_EVT");
break;
case ESP_SPP_WRITE_EVT://write operation completed
log_v("ESP_SPP_WRITE_EVT");
break;
case ESP_SPP_SRV_OPEN_EVT://Server connection open
_spp_client = param->open.handle;
log_i("ESP_SPP_SRV_OPEN_EVT");
break;
default:
break;
}
@ -99,41 +225,76 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
static bool _init_bt(const char *deviceName)
{
if(!_spp_event_group){
_spp_event_group = xEventGroupCreate();
if(!_spp_event_group){
log_e("SPP Event Group Create Failed!");
return false;
}
xEventGroupClearBits(_spp_event_group, 0xFFFFFF);
xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
}
if (_spp_rx_queue == NULL){
_spp_rx_queue = xQueueCreate(RX_QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue
if (_spp_rx_queue == NULL){
log_e("RX Queue Create Failed");
return false;
}
}
if (_spp_tx_queue == NULL){
_spp_tx_queue = xQueueCreate(TX_QUEUE_SIZE, sizeof(spp_packet_t*)); //initialize the queue
if (_spp_tx_queue == NULL){
log_e("TX Queue Create Failed");
return false;
}
}
if(_spp_tx_done == NULL){
_spp_tx_done = xSemaphoreCreateBinary();
if (_spp_tx_done == NULL){
log_e("TX Semaphore Create Failed");
return false;
}
xSemaphoreTake(_spp_tx_done, 0);
}
if(!_spp_task_handle){
xTaskCreate(_spp_tx_task, "spp_tx", 4096, NULL, 2, &_spp_task_handle);
if(!_spp_task_handle){
log_e("Network Event Task Start Failed!");
return false;
}
}
if (!btStarted() && !btStart()){
log_e("%s initialize controller failed\n", __func__);
log_e("initialize controller failed");
return false;
}
esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){
if (esp_bluedroid_init()) {
log_e("%s initialize bluedroid failed\n", __func__);
log_e("initialize bluedroid failed");
return false;
}
}
if (bt_state != ESP_BLUEDROID_STATUS_ENABLED){
if (esp_bluedroid_enable()) {
log_e("%s enable bluedroid failed\n", __func__);
log_e("enable bluedroid failed");
return false;
}
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK){
log_e("%s spp register failed\n", __func__);
log_e("spp register failed");
return false;
}
if (esp_spp_init(ESP_SPP_MODE_CB) != ESP_OK){
log_e("%s spp init failed\n", __func__);
log_e("spp init failed");
return false;
}
_spp_queue = xQueueCreate(QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue
if (_spp_queue == NULL){
log_e("%s Queue creation error\n", __func__);
return false;
}
esp_bt_dev_set_device_name(deviceName);
// the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
@ -142,7 +303,7 @@ static bool _init_bt(const char *deviceName)
cod.minor = 0b000100;
cod.service = 0b00000010110;
if (esp_bt_gap_set_cod(cod, ESP_BT_INIT_COD) != ESP_OK) {
log_e("%s set cod failed\n", __func__);
log_e("set cod failed");
return false;
}
@ -159,6 +320,32 @@ static bool _stop_bt()
esp_bluedroid_deinit();
btStop();
}
_spp_client = 0;
if(_spp_task_handle){
vTaskDelete(_spp_task_handle);
_spp_task_handle = NULL;
}
if(_spp_event_group){
vEventGroupDelete(_spp_event_group);
_spp_event_group = NULL;
}
if(_spp_rx_queue){
vQueueDelete(_spp_rx_queue);
//ToDo: clear RX queue when in packet mode
_spp_rx_queue = NULL;
}
if(_spp_tx_queue){
spp_packet_t *packet = NULL;
while(xQueueReceive(_spp_tx_queue, &packet, 0) == pdTRUE){
free(packet);
}
vQueueDelete(_spp_tx_queue);
_spp_tx_queue = NULL;
}
if (_spp_tx_done) {
vSemaphoreDelete(_spp_tx_done);
_spp_tx_done = NULL;
}
return true;
}
@ -175,7 +362,6 @@ BluetoothSerial::BluetoothSerial()
BluetoothSerial::~BluetoothSerial(void)
{
_stop_bt();
vQueueDelete(_spp_queue);
}
bool BluetoothSerial::begin(String localName)
@ -188,60 +374,39 @@ bool BluetoothSerial::begin(String localName)
int BluetoothSerial::available(void)
{
if (!_spp_client || _spp_queue == NULL){
if (_spp_rx_queue == NULL){
return 0;
}
return uxQueueMessagesWaiting(_spp_queue);
return uxQueueMessagesWaiting(_spp_rx_queue);
}
int BluetoothSerial::peek(void)
{
if (available()){
if (!_spp_client || _spp_queue == NULL){
return 0;
}
uint8_t c;
if (xQueuePeek(_spp_queue, &c, 0)){
return c;
}
uint8_t c;
if (_spp_rx_queue && xQueuePeek(_spp_rx_queue, &c, 0)){
return c;
}
return -1;
}
bool BluetoothSerial::hasClient(void)
{
if (_spp_client)
return true;
return false;
return _spp_client > 0;
}
int BluetoothSerial::read(void)
{
if (available()){
if (!_spp_client || _spp_queue == NULL){
return 0;
}
uint8_t c;
if (xQueueReceive(_spp_queue, &c, 0)){
return c;
}
uint8_t c = 0;
if (_spp_rx_queue && xQueueReceive(_spp_rx_queue, &c, 0)){
return c;
}
return 0;
return -1;
}
size_t BluetoothSerial::write(uint8_t c)
{
if (!_spp_client){
return 0;
}
uint8_t buffer[1];
buffer[0] = c;
esp_err_t err = esp_spp_write(_spp_client, 1, buffer);
return (err == ESP_OK) ? 1 : 0;
return write(&c, 1);
}
size_t BluetoothSerial::write(const uint8_t *buffer, size_t size)
@ -249,24 +414,17 @@ size_t BluetoothSerial::write(const uint8_t *buffer, size_t size)
if (!_spp_client){
return 0;
}
esp_err_t err = esp_spp_write(_spp_client, size, (uint8_t *)buffer);
return (err == ESP_OK) ? size : 0;
return (_spp_queue_packet((uint8_t *)buffer, size) == ESP_OK) ? size : 0;
}
void BluetoothSerial::flush()
{
if (_spp_client){
int qsize = available();
uint8_t buffer[qsize];
esp_spp_write(_spp_client, qsize, buffer);
}
while(read() >= 0){}
}
void BluetoothSerial::end()
{
_stop_bt();
vQueueDelete(_spp_queue);
}
#endif

View File

@ -6,7 +6,7 @@ hw_timer_t *timer = NULL;
void IRAM_ATTR resetModule() {
ets_printf("reboot\n");
esp_restart_noos();
esp_restart();
}
void setup() {

View File

@ -50,12 +50,13 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit)
.init = &sdmmc_host_init,
.set_bus_width = &sdmmc_host_set_bus_width,
.get_bus_width = &sdmmc_host_get_slot_width,
.set_bus_ddr_mode = &sdmmc_host_set_bus_ddr_mode,
.set_card_clk = &sdmmc_host_set_card_clk,
.do_transaction = &sdmmc_host_do_transaction,
.deinit = &sdmmc_host_deinit,
.io_int_enable = sdmmc_host_io_int_enable,
.io_int_wait = sdmmc_host_io_int_wait,
.command_timeout_ms = 0,
.io_int_enable = &sdmmc_host_io_int_enable,
.io_int_wait = &sdmmc_host_io_int_wait,
.command_timeout_ms = 0
};
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
#ifdef BOARD_HAS_1BIT_SDMMC

View File

@ -37,7 +37,7 @@ extern "C" {
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <lwip/ip_addr.h>
#include "apps/dhcpserver_options.h"
#include "dhcpserver/dhcpserver_options.h"
}

View File

@ -38,7 +38,7 @@
{
"packager": "esp32",
"name": "esptool",
"version": "2.3.1"
"version": "2.5.0"
},
{
"packager": "esp32",
@ -85,42 +85,42 @@
},
{
"name": "esptool",
"version": "2.3.1",
"version": "2.5.0",
"systems": [
{
"host": "i686-mingw32",
"url": "https://dl.espressif.com/dl/esptool-2.3.1-windows.zip",
"archiveFileName": "esptool-2.3.1-windows.zip",
"checksum": "SHA-256:c187763d0faac7da7c30a292a23c759bbc256fcd084dc8846ed284000cb0fe29",
"size": "3396085"
"url": "https://dl.espressif.com/dl/esptool-2.5.0-windows.zip",
"archiveFileName": "esptool-2.5.0-windows.zip",
"checksum": "SHA-256:576b8068b577cae0e6e937566a9d32a08ff7ff82963fb60400eacb6691f2fbfb",
"size": "3420959"
},
{
"host": "x86_64-apple-darwin",
"url": "https://dl.espressif.com/dl/esptool-2.3.1-macos.tar.gz",
"archiveFileName": "esptool-2.3.1-macos.tar.gz",
"checksum": "SHA-256:cd922418f02e0ca11dc066b36a22646a1b441da00d762b4464ca598c902c5ecb",
"size": "3810932"
"url": "https://dl.espressif.com/dl/esptool-2.5.0-macos.tar.gz",
"archiveFileName": "esptool-2.5.0-macos.tar.gz",
"checksum": "SHA-256:2da8ba3b83d99b5d808cab955a077e3e0738ec640b51de932d047cad7fac1157",
"size": "3835397"
},
{
"host": "x86_64-pc-linux-gnu",
"url": "https://dl.espressif.com/dl/esptool-2.3.1-linux.tar.gz",
"archiveFileName": "esptool-2.3.1-linux.tar.gz",
"checksum": "SHA-256:cff30841dad80ed5d7d2d58a31843b63afa57528979a9c839806568167691d8e",
"size": "39563"
"url": "https://dl.espressif.com/dl/esptool-2.5.0-linux.tar.gz",
"archiveFileName": "esptool-2.5.0-linux.tar.gz",
"checksum": "SHA-256:34d63b9a0bf2acb9b6fdac15f91a8756f4e722065de031e8fbce4e4abc369e54",
"size": "43468"
},
{
"host": "i686-pc-linux-gnu",
"url": "https://dl.espressif.com/dl/esptool-2.3.1-linux.tar.gz",
"archiveFileName": "esptool-2.3.1-linux.tar.gz",
"checksum": "SHA-256:cff30841dad80ed5d7d2d58a31843b63afa57528979a9c839806568167691d8e",
"size": "39563"
"url": "https://dl.espressif.com/dl/esptool-2.5.0-linux.tar.gz",
"archiveFileName": "esptool-2.5.0-linux.tar.gz",
"checksum": "SHA-256:34d63b9a0bf2acb9b6fdac15f91a8756f4e722065de031e8fbce4e4abc369e54",
"size": "43468"
},
{
"host": "arm-linux-gnueabihf",
"url": "https://dl.espressif.com/dl/esptool-2.3.1-linux.tar.gz",
"archiveFileName": "esptool-2.3.1-linux.tar.gz",
"checksum": "SHA-256:cff30841dad80ed5d7d2d58a31843b63afa57528979a9c839806568167691d8e",
"size": "39563"
"url": "https://dl.espressif.com/dl/esptool-2.5.0-linux.tar.gz",
"archiveFileName": "esptool-2.5.0-linux.tar.gz",
"checksum": "SHA-256:34d63b9a0bf2acb9b6fdac15f91a8756f4e722065de031e8fbce4e4abc369e54",
"size": "43468"
}
]
},

View File

@ -22,7 +22,7 @@ compiler.warning_flags.all=-Wall -Werror=all -Wextra
compiler.path={runtime.tools.xtensa-esp32-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk
compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/bluedroid" "-I{compiler.sdk.path}/include/bluedroid/api" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mbedtls_port" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/wpa_supplicant"
compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/bluedroid" "-I{compiler.sdk.path}/include/bluedroid/api" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp_https_ota" "-I{compiler.sdk.path}/include/esp-mqtt" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/http_server" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mbedtls_port" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/tcp_transport" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/wpa_supplicant"
compiler.c.cmd=xtensa-esp32-elf-gcc
compiler.c.flags=-std=gnu99 -Os -g3 -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wpointer-arith {compiler.warning_flags} -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -MMD -c
@ -35,7 +35,7 @@ compiler.S.flags=-c -g3 -x assembler-with-cpp -MMD -mlongcalls
compiler.c.elf.cmd=xtensa-esp32-elf-gcc
compiler.c.elf.flags=-nostdlib "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld -u ld_include_panic_highint_hdl -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static -Wl,--undefined=uxTopUsedPriority -u __cxa_guard_dummy -u __cxx_fatal_exception
compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lesp_http_client -lhal -lnewlib -ldriver -lbootloader_support -lpp -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -lmdns -lvfs -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lesp-tls -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lsmartconfig_ack -lexpat -lm -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson -lstdc++
compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lhttp_server -lcoexist -lwear_levelling -lesp_http_client -lhal -lnewlib -ldriver -lbootloader_support -lpp -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lesp_ringbuf -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lsmartconfig_ack -lexpat -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson -lesp_https_ota -lstdc++
compiler.as.cmd=xtensa-esp32-elf-as

View File

@ -20,6 +20,7 @@ from __future__ import division, print_function
import argparse
import base64
import binascii
import copy
import hashlib
import inspect
@ -30,10 +31,27 @@ import struct
import sys
import time
import zlib
import string
import serial.tools.list_ports as list_ports
import serial
__version__ = "2.3.1"
# check 'serial' is 'pyserial' and not 'serial' https://github.com/espressif/esptool/issues/269
try:
if "serialization" in serial.__doc__ and "deserialization" in serial.__doc__:
raise ImportError("""
esptool.py depends on pyserial, but there is a conflict with a currently installed package named 'serial'.
You may be able to work around this by 'pip uninstall serial; pip install pyserial' \
but this may break other installed Python software that depends on 'serial'.
There is no good fix for this right now, apart from configuring virtualenvs. \
See https://github.com/espressif/esptool/issues/269#issuecomment-385298196 for discussion of the underlying issue(s).""")
except TypeError:
pass # __doc__ returns None for pyserial
__version__ = "2.5.0"
MAX_UINT32 = 0xffffffff
MAX_UINT24 = 0xffffff
@ -45,6 +63,8 @@ MAX_TIMEOUT = CHIP_ERASE_TIMEOUT * 2 # longest any command can run
SYNC_TIMEOUT = 0.1 # timeout for syncing with bootloader
MD5_TIMEOUT_PER_MB = 8 # timeout (per megabyte) for calculating md5sum
ERASE_REGION_TIMEOUT_PER_MB = 30 # timeout (per megabyte) for erasing a region
MEM_END_ROM_TIMEOUT = 0.05 # special short timeout for ESP_MEM_END, as it may never respond
DEFAULT_SERIAL_WRITE_TIMEOUT = 10 # timeout for serial port write
def timeout_per_mb(seconds_per_mb, size_bytes):
@ -112,7 +132,7 @@ def esp8266_function_only(func):
class ESPLoader(object):
""" Base class providing access to ESP ROM & softtware stub bootloaders.
""" Base class providing access to ESP ROM & software stub bootloaders.
Subclasses provide ESP8266 & ESP32 specific functionality.
Don't instantiate this base class directly, either instantiate a subclass or
@ -200,6 +220,8 @@ class ESPLoader(object):
# https://github.com/espressif/esptool/issues/44#issuecomment-107094446
self._set_port_baudrate(baud)
self._trace_enabled = trace_enabled
# set write timeout, to prevent esptool blocked at write forever.
self._port.write_timeout = DEFAULT_SERIAL_WRITE_TIMEOUT
def _set_port_baudrate(self, baud):
try:
@ -243,7 +265,7 @@ class ESPLoader(object):
buf = b'\xc0' \
+ (packet.replace(b'\xdb',b'\xdb\xdd').replace(b'\xc0',b'\xdb\xdc')) \
+ b'\xc0'
self.trace("Write %d bytes: %r", len(buf), buf)
self.trace("Write %d bytes: %s", len(buf), HexFormatter(buf))
self._port.write(buf)
def trace(self, message, *format_args):
@ -278,8 +300,8 @@ class ESPLoader(object):
try:
if op is not None:
self.trace("command op=0x%02x data len=%s wait_response=%d timeout=%.3f data=%r",
op, len(data), 1 if wait_response else 0, timeout, data)
self.trace("command op=0x%02x data len=%s wait_response=%d timeout=%.3f data=%s",
op, len(data), 1 if wait_response else 0, timeout, HexFormatter(data))
pkt = struct.pack(b'<BBHI', 0x00, op, len(data), chk) + data
self.write(pkt)
@ -342,6 +364,16 @@ class ESPLoader(object):
for i in range(7):
self.command()
def _setDTR(self, state):
self._port.setDTR(state)
def _setRTS(self, state):
self._port.setRTS(state)
# Work-around for adapters on Windows using the usbser.sys driver:
# generate a dummy change to DTR so that the set-control-line-state
# request is sent with the updated RTS state and the same DTR state
self._port.setDTR(self._port.dtr)
def _connect_attempt(self, mode='default_reset', esp32r0_delay=False):
""" A single connection attempt, with esp32r0 workaround options """
# esp32r0_delay is a workaround for bugs with the most common auto reset
@ -355,6 +387,11 @@ class ESPLoader(object):
# Details: https://github.com/espressif/esptool/issues/136
last_error = None
# If we're doing no_sync, we're likely communicating as a pass through
# with an intermediate device to the ESP32
if mode == "no_reset_no_sync":
return last_error
# issue reset-to-bootloader:
# RTS = either CH_PD/EN or nRESET (both active low = chip in reset
# DTR = GPIO0 (active low = boot to flasher)
@ -362,23 +399,23 @@ class ESPLoader(object):
# DTR & RTS are active low signals,
# ie True = pin @ 0V, False = pin @ VCC.
if mode != 'no_reset':
self._port.setDTR(False) # IO0=HIGH
self._port.setRTS(True) # EN=LOW, chip in reset
self._setDTR(False) # IO0=HIGH
self._setRTS(True) # EN=LOW, chip in reset
time.sleep(0.1)
if esp32r0_delay:
# Some chips are more likely to trigger the esp32r0
# watchdog reset silicon bug if they're held with EN=LOW
# for a longer period
time.sleep(1.2)
self._port.setDTR(True) # IO0=LOW
self._port.setRTS(False) # EN=HIGH, chip out of reset
self._setDTR(True) # IO0=LOW
self._setRTS(False) # EN=HIGH, chip out of reset
if esp32r0_delay:
# Sleep longer after reset.
# This workaround only works on revision 0 ESP32 chips,
# it exploits a silicon bug spurious watchdog reset.
time.sleep(0.4) # allow watchdog reset to occur
time.sleep(0.05)
self._port.setDTR(False) # IO0=HIGH, done
self._setDTR(False) # IO0=HIGH, done
for _ in range(5):
try:
@ -403,7 +440,7 @@ class ESPLoader(object):
last_error = None
try:
for _ in range(10):
for _ in range(7):
last_error = self._connect_attempt(mode=mode, esp32r0_delay=False)
if last_error is None:
return
@ -431,6 +468,18 @@ class ESPLoader(object):
""" Start downloading an application image to RAM """
def mem_begin(self, size, blocks, blocksize, offset):
if self.IS_STUB: # check we're not going to overwrite a running stub with this data
stub = self.STUB_CODE
load_start = offset
load_end = offset + size
for (start, end) in [(stub["data_start"], stub["data_start"] + len(stub["data"])),
(stub["text_start"], stub["text_start"] + len(stub["text"]))]:
if load_start < end and load_end > start:
raise FatalError(("Software loader is resident at 0x%08x-0x%08x. " +
"Can't load binary at overlapping address range 0x%08x-0x%08x. " +
"Either change binary loading address, or use the --no-stub " +
"option to disable the software loader.") % (start, end, load_start, load_end))
return self.check_command("enter RAM download mode", self.ESP_MEM_BEGIN,
struct.pack('<IIII', size, blocks, blocksize, offset))
@ -442,8 +491,19 @@ class ESPLoader(object):
""" Leave download mode and run the application """
def mem_finish(self, entrypoint=0):
return self.check_command("leave RAM download mode", self.ESP_MEM_END,
struct.pack('<II', int(entrypoint == 0), entrypoint))
# Sending ESP_MEM_END usually sends a correct response back, however sometimes
# (with ROM loader) the executed code may reset the UART or change the baud rate
# before the transmit FIFO is empty. So in these cases we set a short timeout and
# ignore errors.
timeout = DEFAULT_TIMEOUT if self.IS_STUB else MEM_END_ROM_TIMEOUT
data = struct.pack('<II', int(entrypoint == 0), entrypoint)
try:
return self.check_command("leave RAM download mode", self.ESP_MEM_END,
data=data, timeout=timeout)
except FatalError:
if self.IS_STUB:
raise
pass
""" Start downloading to Flash (performs an erase)
@ -822,9 +882,9 @@ class ESPLoader(object):
self.run_spiflash_command(SPIFLASH_WRDI)
def hard_reset(self):
self._port.setRTS(True) # EN->LOW
self._setRTS(True) # EN->LOW
time.sleep(0.1)
self._port.setRTS(False)
self._setRTS(False)
def soft_reset(self, stay_in_bootloader):
if not self.IS_STUB:
@ -892,7 +952,7 @@ class ESP8266ROM(ESPLoader):
return "ESP8285" if is_8285 else "ESP8266EX"
def get_chip_features(self):
features = [ "WiFi" ]
features = ["WiFi"]
if self.get_chip_description() == "ESP8285":
features += ["Embedded Flash"]
return features
@ -911,7 +971,7 @@ class ESP8266ROM(ESPLoader):
super(ESP8266ROM, self).flash_set_parameters(size)
def chip_id(self):
""" Read Chip ID from OTP ROM - see http://esp8266-re.foogod.com/wiki/System_get_chip_id_%28IoT_RTOS_SDK_0.9.9%29 """
""" Read Chip ID from efuse - the equivalent of the SDK system_get_chip_id() function """
id0 = self.read_reg(self.ESP_OTP_MAC0)
id1 = self.read_reg(self.ESP_OTP_MAC1)
return (id0 >> 24) | ((id1 & MAX_UINT24) << 8)
@ -950,6 +1010,9 @@ class ESP8266ROM(ESPLoader):
else:
return (num_sectors - head_sectors) * sector_size
def override_vddsdio(self, new_voltage):
raise NotImplementedInROMError("Overriding VDDSDIO setting only applies to ESP32")
class ESP8266StubLoader(ESP8266ROM):
""" Access class for ESP8266 stub loader, runs on top of ROM.
@ -1002,17 +1065,13 @@ class ESP32ROM(ESPLoader):
BOOTLOADER_FLASH_OFFSET = 0x1000
OVERRIDE_VDDSDIO_CHOICES = ["1.8V", "1.9V", "OFF"]
def get_chip_description(self):
word3 = self.read_efuse(3)
chip_version = (word3 >> 12) & 0xF
chip_ver_rev1 = (word3 >> 15) & 0x1
pkg_version = (word3 >> 9) & 0x07
silicon_rev = {
0x0: "0",
0x8: "1",
0xc: "1", # Silicon rev 1 w/ BLK3_PART_RESERVE bit set
}.get(chip_version, "(unknown 0x%x)" % chip_version)
chip_name = {
0: "ESP32D0WDQ6",
1: "ESP32D0WDQ5",
@ -1020,27 +1079,41 @@ class ESP32ROM(ESPLoader):
5: "ESP32-PICO-D4",
}.get(pkg_version, "unknown ESP32")
return "%s (revision %s)" % (chip_name, silicon_rev)
return "%s (revision %d)" % (chip_name, chip_ver_rev1)
def get_chip_features(self):
features = ["WiFi"]
word3 = self.read_efuse(3)
if word3 & (1 << 1) == 0: # RD_CHIP_VER_DIS_BT
# names of variables in this section are lowercase
# versions of EFUSE names as documented in TRM and
# ESP-IDF efuse_reg.h
chip_ver_dis_bt = word3 & (1 << 1)
if chip_ver_dis_bt == 0:
features += ["BT"]
if word3 & (1 << 0): # RD_CHIP_VER_DIS_APP_CPU
chip_ver_dis_app_cpu = word3 & (1 << 0)
if chip_ver_dis_app_cpu:
features += ["Single Core"]
else:
features += ["Dual Core"]
chip_cpu_freq_rated = word3 & (1 << 13)
if chip_cpu_freq_rated:
chip_cpu_freq_low = word3 & (1 << 12)
if chip_cpu_freq_low:
features += ["160MHz"]
else:
features += ["240MHz"]
pkg_version = (word3 >> 9) & 0x07
if pkg_version != 0:
if pkg_version in [2, 4, 5]:
features += ["Embedded Flash"]
word4 = self.read_efuse(4)
vref = (word4 >> 8) & 0x1F
if vref != 0:
adc_vref = (word4 >> 8) & 0x1F
if adc_vref:
features += ["VRef calibration in efuse"]
return features
@ -1050,9 +1123,7 @@ class ESP32ROM(ESPLoader):
return self.read_reg(self.EFUSE_REG_BASE + (4 * n))
def chip_id(self):
word16 = self.read_efuse(1)
word17 = self.read_efuse(2)
return ((word17 & MAX_UINT24) << 24) | (word16 >> 8) & MAX_UINT24
raise NotSupportedError(self, "chip_id")
def read_mac(self):
""" Read MAC from EFUSE region """
@ -1067,6 +1138,28 @@ class ESP32ROM(ESPLoader):
def get_erase_size(self, offset, size):
return size
def override_vddsdio(self, new_voltage):
new_voltage = new_voltage.upper()
if new_voltage not in self.OVERRIDE_VDDSDIO_CHOICES:
raise FatalError("The only accepted VDDSDIO overrides are '1.8V', '1.9V' and 'OFF'")
RTC_CNTL_SDIO_CONF_REG = 0x3ff48074
RTC_CNTL_XPD_SDIO_REG = (1 << 31)
RTC_CNTL_DREFH_SDIO_M = (3 << 29)
RTC_CNTL_DREFM_SDIO_M = (3 << 27)
RTC_CNTL_DREFL_SDIO_M = (3 << 25)
# RTC_CNTL_SDIO_TIEH = (1 << 23) # not used here, setting TIEH=1 would set 3.3V output, not safe for esptool.py to do
RTC_CNTL_SDIO_FORCE = (1 << 22)
RTC_CNTL_SDIO_PD_EN = (1 << 21)
reg_val = RTC_CNTL_SDIO_FORCE # override efuse setting
reg_val |= RTC_CNTL_SDIO_PD_EN
if new_voltage != "OFF":
reg_val |= RTC_CNTL_XPD_SDIO_REG # enable internal LDO
if new_voltage == "1.9V":
reg_val |= (RTC_CNTL_DREFH_SDIO_M | RTC_CNTL_DREFM_SDIO_M | RTC_CNTL_DREFL_SDIO_M) # boost voltage
self.write_reg(RTC_CNTL_SDIO_CONF_REG, reg_val)
print("VDDSDIO regulator set to %s" % new_voltage)
class ESP32StubLoader(ESP32ROM):
""" Access class for ESP32 stub loader, runs on top of ROM.
@ -1096,20 +1189,20 @@ class ESPBOOTLOADER(object):
def LoadFirmwareImage(chip, filename):
""" Load a firmware image. Can be for ESP8266 or ESP32. ESP8266 images will be examined to determine if they are
original ROM firmware images (ESPFirmwareImage) or "v2" OTA bootloader images.
original ROM firmware images (ESP8266ROMFirmwareImage) or "v2" OTA bootloader images.
Returns a BaseFirmwareImage subclass, either ESPFirmwareImage (v1) or OTAFirmwareImage (v2).
Returns a BaseFirmwareImage subclass, either ESP8266ROMFirmwareImage (v1) or ESP8266V2FirmwareImage (v2).
"""
with open(filename, 'rb') as f:
if chip == 'esp32':
if chip.lower() == 'esp32':
return ESP32FirmwareImage(f)
else: # Otherwise, ESP8266 so look at magic to determine the image type
magic = ord(f.read(1))
f.seek(0)
if magic == ESPLoader.ESP_IMAGE_MAGIC:
return ESPFirmwareImage(f)
return ESP8266ROMFirmwareImage(f)
elif magic == ESPBOOTLOADER.IMAGE_V2_MAGIC:
return OTAFirmwareImage(f)
return ESP8266V2FirmwareImage(f)
else:
raise FatalError("Invalid image magic number: %d" % magic)
@ -1119,10 +1212,11 @@ class ImageSegment(object):
(very similar to a section in an ELFImage also) """
def __init__(self, addr, data, file_offs=None):
self.addr = addr
# pad all ImageSegments to at least 4 bytes length
self.data = pad_to(data, 4, b'\x00')
self.data = data
self.file_offs = file_offs
self.include_in_checksum = True
if self.addr != 0:
self.pad_to_alignment(4) # pad all "real" ImageSegments 4 byte aligned length
def copy_with_new_addr(self, new_addr):
""" Return a new ImageSegment with same data, but mapped at
@ -1147,6 +1241,9 @@ class ImageSegment(object):
r += " file_offs 0x%08x" % (self.file_offs)
return r
def pad_to_alignment(self, alignment):
self.data = pad_to(self.data, alignment, b'\x00')
class ELFSection(ImageSegment):
""" Wrapper class for a section in an ELF image, has a section
@ -1243,13 +1340,13 @@ class BaseFirmwareImage(object):
return [s for s in self.segments if s != irom_segment]
class ESPFirmwareImage(BaseFirmwareImage):
class ESP8266ROMFirmwareImage(BaseFirmwareImage):
""" 'Version 1' firmware image, segments loaded directly by the ROM bootloader. """
ROM_LOADER = ESP8266ROM
def __init__(self, load_file=None):
super(ESPFirmwareImage, self).__init__()
super(ESP8266ROMFirmwareImage, self).__init__()
self.flash_mode = 0
self.flash_size_freq = 0
self.version = 1
@ -1283,7 +1380,7 @@ class ESPFirmwareImage(BaseFirmwareImage):
self.append_checksum(f, checksum)
class OTAFirmwareImage(BaseFirmwareImage):
class ESP8266V2FirmwareImage(BaseFirmwareImage):
""" 'Version 2' firmware image, segments loaded by software bootloader stub
(ie Espressif bootloader or rboot)
"""
@ -1291,7 +1388,7 @@ class OTAFirmwareImage(BaseFirmwareImage):
ROM_LOADER = ESP8266ROM
def __init__(self, load_file=None):
super(OTAFirmwareImage, self).__init__()
super(ESP8266V2FirmwareImage, self).__init__()
self.version = 2
if load_file is not None:
segments = self.load_common_header(load_file, ESPBOOTLOADER.IMAGE_V2_MAGIC)
@ -1304,8 +1401,7 @@ class OTAFirmwareImage(BaseFirmwareImage):
# the file is saved in the image with a zero load address
# in the header, so we need to calculate a load address
irom_segment = self.load_segment(load_file, True)
# for actual mapped addr, add ESP8266ROM.IROM_MAP_START + flashing_Addr + 8
irom_segment.addr = 0
irom_segment.addr = 0 # for actual mapped addr, add ESP8266ROM.IROM_MAP_START + flashing_addr + 8
irom_segment.include_in_checksum = False
first_flash_mode = self.flash_mode
@ -1350,6 +1446,7 @@ class OTAFirmwareImage(BaseFirmwareImage):
if irom_segment is not None:
# save irom0 segment, make sure it has load addr 0 in the file
irom_segment = irom_segment.copy_with_new_addr(0)
irom_segment.pad_to_alignment(16) # irom_segment must end on a 16 byte boundary
self.save_segment(f, irom_segment)
# second header, matches V1 header and contains loadable segments
@ -1360,6 +1457,29 @@ class OTAFirmwareImage(BaseFirmwareImage):
checksum = self.save_segment(f, segment, checksum)
self.append_checksum(f, checksum)
# calculate a crc32 of entire file and append
# (algorithm used by recent 8266 SDK bootloaders)
with open(filename, 'rb') as f:
crc = esp8266_crc32(f.read())
with open(filename, 'ab') as f:
f.write(struct.pack(b'<I', crc))
# Backwards compatibility for previous API, remove in esptool.py V3
ESPFirmwareImage = ESP8266ROMFirmwareImage
OTAFirmwareImage = ESP8266V2FirmwareImage
def esp8266_crc32(data):
"""
CRC32 algorithm used by 8266 SDK bootloader (and gen_appbin.py).
"""
crc = binascii.crc32(data, 0) & 0xFFFFFFFF
if crc & 0x80000000:
return crc ^ 0xFFFFFFFF
else:
return crc + 1
class ESP32FirmwareImage(BaseFirmwareImage):
""" ESP32 firmware image is very similar to V1 ESP8266 image,
@ -1380,6 +1500,7 @@ class ESP32FirmwareImage(BaseFirmwareImage):
def __init__(self, load_file=None):
super(ESP32FirmwareImage, self).__init__()
self.secure_pad = False
self.flash_mode = 0
self.flash_size_freq = 0
self.version = 1
@ -1496,11 +1617,31 @@ class ESP32FirmwareImage(BaseFirmwareImage):
checksum = self.save_segment(f, segment, checksum)
total_segments += 1
if self.secure_pad:
# pad the image so that after signing it will end on a a 64KB boundary.
# This ensures all mapped flash content will be verified.
if not self.append_digest:
raise FatalError("secure_pad only applies if a SHA-256 digest is also appended to the image")
align_past = (f.tell() + self.SEG_HEADER_LEN) % IROM_ALIGN
# 16 byte aligned checksum (force the alignment to simplify calculations)
checksum_space = 16
# after checksum: SHA-256 digest + (to be added by signing process) version, signature + 12 trailing bytes due to alignment
space_after_checksum = 32 + 4 + 64 + 12
pad_len = (IROM_ALIGN - align_past - checksum_space - space_after_checksum) % IROM_ALIGN
pad_segment = ImageSegment(0, b'\x00' * pad_len, f.tell())
checksum = self.save_segment(f, pad_segment, checksum)
total_segments += 1
# done writing segments
self.append_checksum(f, checksum)
image_length = f.tell()
if self.secure_pad:
assert ((image_length + space_after_checksum) % IROM_ALIGN) == 0
# kinda hacky: go back to the initial header and write the new segment count
# that includes padding segments. This header is not checksummed
image_length = f.tell()
f.seek(1)
try:
f.write(chr(total_segments))
@ -1653,7 +1794,7 @@ def slip_reader(port, trace_function):
waiting_for = "header" if partial_packet is None else "content"
trace_function("Timed out waiting for packet %s", waiting_for)
raise FatalError("Timed out waiting for packet %s" % waiting_for)
trace_function("Read %d bytes: %r", len(read_bytes), read_bytes)
trace_function("Read %d bytes: %s", len(read_bytes), HexFormatter(read_bytes))
for b in read_bytes:
if type(b) is int:
b = bytes([b]) # python 2/3 compat
@ -1662,9 +1803,9 @@ def slip_reader(port, trace_function):
if b == b'\xc0':
partial_packet = b""
else:
trace_function("Read invalid data: %r", read_bytes)
trace_function("Remaining data in serial buffer: %r", port.read(port.inWaiting()))
raise FatalError('Invalid head of packet (%r)' % b)
trace_function("Read invalid data: %s", HexFormatter(read_bytes))
trace_function("Remaining data in serial buffer: %s", HexFormatter(port.read(port.inWaiting())))
raise FatalError('Invalid head of packet (0x%s)' % hexify(b))
elif in_escape: # part-way through escape sequence
in_escape = False
if b == b'\xdc':
@ -1672,13 +1813,13 @@ def slip_reader(port, trace_function):
elif b == b'\xdd':
partial_packet += b'\xdb'
else:
trace_function("Read invalid data: %r", read_bytes)
trace_function("Remaining data in serial buffer: %r", port.read(port.inWaiting()))
raise FatalError('Invalid SLIP escape (%r%r)' % (b'\xdb', b))
trace_function("Read invalid data: %s", HexFormatter(read_bytes))
trace_function("Remaining data in serial buffer: %s", HexFormatter(port.read(port.inWaiting())))
raise FatalError('Invalid SLIP escape (0xdb, 0x%s)' % (hexify(b)))
elif b == b'\xdb': # start of escape sequence
in_escape = True
elif b == b'\xc0': # end of packet
trace_function("Full packet: %r", partial_packet)
trace_function("Received full packet: %s", HexFormatter(partial_packet))
yield partial_packet
partial_packet = None
else: # normal byte in packet
@ -1715,25 +1856,47 @@ def flash_size_bytes(size):
raise FatalError("Unknown size %s" % size)
def hexify(s):
def hexify(s, uppercase=True):
format_str = '%02X' if uppercase else '%02x'
if not PYTHON2:
return ''.join('%02X' % c for c in s)
return ''.join(format_str % c for c in s)
else:
return ''.join('%02X' % ord(c) for c in s)
return ''.join(format_str % ord(c) for c in s)
def unhexify(hs):
s = bytes()
class HexFormatter(object):
"""
Wrapper class which takes binary data in its constructor
and returns a hex string as it's __str__ method.
for i in range(0, len(hs) - 1, 2):
hex_string = hs[i:i + 2]
This is intended for "lazy formatting" of trace() output
in hex format. Avoids overhead (significant on slow computers)
of generating long hex strings even if tracing is disabled.
if not PYTHON2:
s += bytes([int(hex_string, 16)])
Note that this doesn't save any overhead if passed as an
argument to "%", only when passed to trace()
If auto_split is set (default), any long line (> 16 bytes) will be
printed as separately indented lines, with ASCII decoding at the end
of each line.
"""
def __init__(self, binary_string, auto_split=True):
self._s = binary_string
self._auto_split = auto_split
def __str__(self):
if self._auto_split and len(self._s) > 16:
result = ""
s = self._s
while len(s) > 0:
line = s[:16]
ascii_line = "".join(c if (c == ' ' or (c in string.printable and c not in string.whitespace))
else '.' for c in line.decode('ascii', 'replace'))
s = s[16:]
result += "\n %-16s %-16s | %s" % (hexify(line[:8], False), hexify(line[8:], False), ascii_line)
return result
else:
s += chr(int(hex_string, 16))
return s
return hexify(self._s, False)
def pad_to(data, alignment, pad_character=b'\xFF'):
@ -1770,6 +1933,11 @@ class NotImplementedInROMError(FatalError):
def __init__(self, bootloader, func):
FatalError.__init__(self, "%s ROM does not support function %s." % (bootloader.CHIP_NAME, func.__name__))
class NotSupportedError(FatalError):
def __init__(self, esp, function_name):
FatalError.__init__(self, "Function %s is not supported for %s." % (function_name, esp.CHIP_NAME))
# "Operation" commands, executable at command line. One function each
#
# Each function takes either two args (<ESPLoader instance>, <args>) or a single <args>
@ -1777,18 +1945,19 @@ class NotImplementedInROMError(FatalError):
def load_ram(esp, args):
image = LoadFirmwareImage(esp, args.filename)
image = LoadFirmwareImage(esp.CHIP_NAME, args.filename)
print('RAM boot...')
for (offset, size, data) in image.segments:
print('Downloading %d bytes at %08x...' % (size, offset), end=' ')
for seg in image.segments:
size = len(seg.data)
print('Downloading %d bytes at %08x...' % (size, seg.addr), end=' ')
sys.stdout.flush()
esp.mem_begin(size, div_roundup(size, esp.ESP_RAM_BLOCK), esp.ESP_RAM_BLOCK, offset)
esp.mem_begin(size, div_roundup(size, esp.ESP_RAM_BLOCK), esp.ESP_RAM_BLOCK, seg.addr)
seq = 0
while len(data) > 0:
esp.mem_block(data[0:esp.ESP_RAM_BLOCK], seq)
data = data[esp.ESP_RAM_BLOCK:]
while len(seg.data) > 0:
esp.mem_block(seg.data[0:esp.ESP_RAM_BLOCK], seq)
seg.data = seg.data[esp.ESP_RAM_BLOCK:]
seq += 1
print('done!')
@ -1974,7 +2143,7 @@ def image_info(args):
def make_image(args):
image = ESPFirmwareImage()
image = ESP8266ROMFirmwareImage()
if len(args.segfile) == 0:
raise FatalError('No segments specified')
if len(args.segfile) != len(args.segaddr):
@ -1994,10 +2163,11 @@ def elf2image(args):
if args.chip == 'esp32':
image = ESP32FirmwareImage()
image.secure_pad = args.secure_pad
elif args.version == '1': # ESP8266
image = ESPFirmwareImage()
image = ESP8266ROMFirmwareImage()
else:
image = OTAFirmwareImage()
image = ESP8266V2FirmwareImage()
image.entrypoint = e.entrypoint
image.segments = e.sections # ELFSection is a subclass of ImageSegment
image.flash_mode = {'qio':0, 'qout':1, 'dio':2, 'dout': 3}[args.flash_mode]
@ -2018,8 +2188,12 @@ def read_mac(esp, args):
def chip_id(esp, args):
chipid = esp.chip_id()
print('Chip ID: 0x%08x' % chipid)
try:
chipid = esp.chip_id()
print('Chip ID: 0x%08x' % chipid)
except NotSupportedError:
print('Warning: %s has no Chip ID. Reading MAC instead.' % esp.CHIP_NAME)
read_mac(esp, args)
def erase_flash(esp, args):
@ -2137,7 +2311,7 @@ def main():
parser.add_argument(
'--port', '-p',
help='Serial port device',
default=os.environ.get('ESPTOOL_PORT', ESPLoader.DEFAULT_PORT))
default=os.environ.get('ESPTOOL_PORT', None))
parser.add_argument(
'--baud', '-b',
@ -2148,7 +2322,7 @@ def main():
parser.add_argument(
'--before',
help='What to do before connecting to the chip',
choices=['default_reset', 'no_reset'],
choices=['default_reset', 'no_reset', 'no_reset_no_sync'],
default=os.environ.get('ESPTOOL_BEFORE', 'default_reset'))
parser.add_argument(
@ -2167,6 +2341,12 @@ def main():
help="Enable trace-level output of esptool.py interactions.",
action='store_true')
parser.add_argument(
'--override-vddsdio',
help="Override ESP32 VDDSDIO internal voltage regulator (use with care)",
choices=ESP32ROM.OVERRIDE_VDDSDIO_CHOICES,
nargs='?')
subparsers = parser.add_subparsers(
dest='operation',
help='Run esptool {command} -h for additional help')
@ -2253,6 +2433,7 @@ def main():
parser_elf2image.add_argument('input', help='Input ELF file')
parser_elf2image.add_argument('--output', '-o', help='Output filename prefix (for version 1 image), or filename (for version 2 single image)', type=str)
parser_elf2image.add_argument('--version', '-e', help='Output image version', choices=['1','2'], default='1')
parser_elf2image.add_argument('--secure-pad', action='store_true', help='Pad image so once signed it will end on a 64KB boundary. For ESP32 images only.')
add_spi_flash_subparsers(parser_elf2image, is_elf2image=True)
@ -2344,24 +2525,50 @@ def main():
operation_args = inspect.getfullargspec(operation_func).args
if operation_args[0] == 'esp': # operation function takes an ESPLoader connection object
initial_baud = min(ESPLoader.ESP_ROM_BAUD, args.baud) # don't sync faster than the default baud rate
if args.chip == 'auto':
esp = ESPLoader.detect_chip(args.port, initial_baud, args.before, args.trace)
if args.before != "no_reset_no_sync":
initial_baud = min(ESPLoader.ESP_ROM_BAUD, args.baud) # don't sync faster than the default baud rate
else:
chip_class = {
'esp8266': ESP8266ROM,
'esp32': ESP32ROM,
}[args.chip]
esp = chip_class(args.port, initial_baud, args.trace)
esp.connect(args.before)
initial_baud = args.baud
if args.port is None:
ser_list = sorted(ports.device for ports in list_ports.comports())
print("Found %d serial ports" % len(ser_list))
else:
ser_list = [args.port]
esp = None
for each_port in reversed(ser_list):
print("Serial port %s" % each_port)
try:
if args.chip == 'auto':
esp = ESPLoader.detect_chip(each_port, initial_baud, args.before, args.trace)
else:
chip_class = {
'esp8266': ESP8266ROM,
'esp32': ESP32ROM,
}[args.chip]
esp = chip_class(each_port, initial_baud, args.trace)
esp.connect(args.before)
break
except FatalError as err:
if args.port is not None:
raise
print("%s failed to connect: %s" % (each_port, err))
esp = None
if esp is None:
raise FatalError("All of the %d available serial ports could not connect to a Espressif device." % len(ser_list))
print("Chip is %s" % (esp.get_chip_description()))
print("Features: %s" % ", ".join(esp.get_chip_features()))
read_mac(esp, args)
if not args.no_stub:
esp = esp.run_stub()
if args.override_vddsdio:
esp.override_vddsdio(args.override_vddsdio)
if args.baud > initial_baud:
try:
esp.change_baud(args.baud)
@ -2386,8 +2593,11 @@ def main():
operation_func(esp, args)
# finish execution based on args.after
if args.after == 'hard_reset':
# Handle post-operation behaviour (reset or other)
if operation_func == load_ram:
# the ESP is now running the loaded image, so let it run
print('Exiting immediately.')
elif args.after == 'hard_reset':
print('Hard resetting via RTS pin...')
esp.hard_reset()
elif args.after == 'soft_reset':
@ -2399,6 +2609,8 @@ def main():
if esp.IS_STUB:
esp.soft_reset(True) # exit stub back to ROM loader
esp._port.close()
else:
operation_func(args)
@ -2497,7 +2709,7 @@ class AddrFilenamePairAction(argparse.Action):
for i in range(0,len(values),2):
try:
address = int(values[i],0)
except ValueError as e:
except ValueError:
raise argparse.ArgumentError(self,'Address "%s" must be a number' % values[i])
try:
argfile = open(values[i + 1], 'rb')
@ -2524,104 +2736,104 @@ class AddrFilenamePairAction(argparse.Action):
# Binary stub code (see flasher_stub dir for source & details)
ESP8266ROM.STUB_CODE = eval(zlib.decompress(base64.b64decode(b"""
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\
neIoDdsQM/v3/wLWvxs5\
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\
nORxF3HqX/8XohBRvg==\
""")))
ESP32ROM.STUB_CODE = eval(zlib.decompress(base64.b64decode(b"""
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\
S0yomEyqQut//QdAk8Ky\
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\
""")))

Binary file not shown.

View File

@ -62,6 +62,7 @@ SUBTYPES = {
quiet = False
md5sum = True
secure = False
offset_part_table = 0
def status(msg):
@ -95,19 +96,23 @@ class PartitionTable(list):
if line.startswith("#") or len(line) == 0:
continue
try:
res.append(PartitionDefinition.from_csv(line))
res.append(PartitionDefinition.from_csv(line, line_no+1))
except InputError as e:
raise InputError("Error at line %d: %s" % (line_no+1, e))
except Exception:
critical("Unexpected error parsing line %d: %s" % (line_no+1, line))
critical("Unexpected error parsing CSV line %d: %s" % (line_no+1, line))
raise
# fix up missing offsets & negative sizes
last_end = offset_part_table + PARTITION_TABLE_SIZE # first offset after partition table
for e in res:
if offset_part_table != 0 and e.offset is not None and e.offset < last_end:
critical("WARNING: 0x%x address in the partition table is below 0x%x" % (e.offset, last_end))
e.offset = None
if e.offset is not None and e.offset < last_end:
if e == res[0]:
raise InputError("CSV Error: First partition offset 0x%x overlaps end of partition table 0x%x"
% (e.offset, last_end))
else:
raise InputError("CSV Error: Partitions overlap. Partition at line %d sets offset 0x%x. Previous partition ends 0x%x"
% (e.line_no, e.offset, last_end))
if e.offset is None:
pad_to = 0x10000 if e.type == APP_TYPE else 4
if last_end % pad_to != 0:
@ -164,6 +169,19 @@ class PartitionTable(list):
# verify each partition individually
for p in self:
p.verify()
# check on duplicate name
names = [ p.name for p in self ]
duplicates = set( n for n in names if names.count(n) > 1 )
# print sorted duplicate partitions by name
if len(duplicates) != 0:
print("A list of partitions that have the same name:")
for p in sorted(self, key=lambda x:x.name):
if len(duplicates.intersection([p.name])) != 0:
print("%s" % (p.to_csv()))
raise InputError("Partition names must be unique")
# check for overlaps
last = None
for p in sorted(self, key=lambda x:x.offset):
@ -245,12 +263,13 @@ class PartitionDefinition(object):
self.encrypted = False
@classmethod
def from_csv(cls, line):
def from_csv(cls, line, line_no):
""" Parse a line from the CSV """
line_w_defaults = line + ",,,," # lazy way to support default fields
fields = [ f.strip() for f in line_w_defaults.split(",") ]
res = PartitionDefinition()
res.line_no = line_no
res.name = fields[0]
res.type = res.parse_type(fields[1])
res.subtype = res.parse_subtype(fields[2])
@ -322,6 +341,8 @@ class PartitionDefinition(object):
align = self.ALIGNMENT.get(self.type, 4)
if self.offset % align:
raise ValidationError(self, "Offset 0x%x is not aligned to 0x%x" % (self.offset, align))
if self.size % align and secure:
raise ValidationError(self, "Size 0x%x is not aligned to 0x%x" % (self.size, align))
if self.size is None:
raise ValidationError(self, "Size field is not set")
@ -414,6 +435,7 @@ def main():
global quiet
global md5sum
global offset_part_table
global secure
parser = argparse.ArgumentParser(description='ESP32 partition table utility')
parser.add_argument('--flash-size', help='Optional flash size limit, checks partition table fits in flash',
@ -423,7 +445,7 @@ def main():
parser.add_argument('--verify', '-v', help="Verify partition table fields (deprecated, this behaviour is enabled by default and this flag does nothing.", action='store_true')
parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true')
parser.add_argument('--offset', '-o', help='Set offset partition table', default='0x8000')
parser.add_argument('--secure', help="Require app partitions to be suitable for secure boot", action='store_true')
parser.add_argument('input', help='Path to CSV or binary file to parse.', type=argparse.FileType('rb'))
parser.add_argument('output', help='Path to output converted binary or CSV file. Will use stdout if omitted.',
nargs='?', default='-')
@ -432,6 +454,7 @@ def main():
quiet = args.quiet
md5sum = not args.disable_md5sum
secure = args.secure
offset_part_table = int(args.offset, 0)
input = args.input.read()
input_is_binary = input[0:2] == PartitionDefinition.MAGIC_BYTES

View File

@ -107,11 +107,14 @@ env.Append(
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp32"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_adc_cal"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_http_client"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp_https_ota"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-mqtt"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-tls"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "ethernet"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "fatfs"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "freertos"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "heap"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "http_server"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "jsmn"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "log"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "mdns"),
@ -125,15 +128,16 @@ env.Append(
join(FRAMEWORK_DIR, "tools", "sdk", "include", "smartconfig_ack"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "spiffs"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcpip_adapter"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "tcp_transport"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "ulp"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "vfs"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "wear_levelling"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "xtensa-debug-module"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "lwip"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "coap"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "console"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "expat"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "json"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "lwip"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "newlib"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "nghttp"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "soc"),
@ -147,7 +151,7 @@ env.Append(
],
LIBS=[
"gcc", "openssl", "btdm_app", "fatfs", "wps", "coexist", "wear_levelling", "esp_http_client", "hal", "newlib", "driver", "bootloader_support", "pp", "mesh", "smartconfig", "jsmn", "wpa", "ethernet", "phy", "app_trace", "console", "ulp", "wpa_supplicant", "freertos", "bt", "micro-ecc", "cxx", "xtensa-debug-module", "mdns", "vfs", "soc", "core", "sdmmc", "coap", "tcpip_adapter", "c_nano", "esp-tls", "rtc", "spi_flash", "wpa2", "esp32", "app_update", "nghttp", "spiffs", "espnow", "nvs_flash", "esp_adc_cal", "log", "smartconfig_ack", "expat", "m", "c", "heap", "mbedtls", "lwip", "net80211", "pthread", "json", "stdc++"
"gcc", "openssl", "btdm_app", "fatfs", "wps", "http_server", "coexist", "wear_levelling", "esp_http_client", "hal", "newlib", "driver", "bootloader_support", "pp", "mesh", "smartconfig", "jsmn", "wpa", "ethernet", "phy", "app_trace", "console", "ulp", "wpa_supplicant", "freertos", "bt", "micro-ecc", "cxx", "xtensa-debug-module", "tcp_transport", "mdns", "vfs", "esp_ringbuf", "soc", "core", "sdmmc", "coap", "tcpip_adapter", "c_nano", "esp-tls", "asio", "rtc", "spi_flash", "wpa2", "esp32", "app_update", "nghttp", "spiffs", "espnow", "nvs_flash", "esp_adc_cal", "log", "smartconfig_ack", "expat", "m", "mqtt", "c", "heap", "mbedtls", "lwip", "net80211", "pthread", "json", "esp_https_ota", "stdc++"
],
LIBSOURCE_DIRS=[

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -20,7 +20,6 @@
#include <stddef.h>
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_spi_flash.h"
#ifdef __cplusplus
extern "C"
@ -133,7 +132,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
*
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
* returned partition contains a bootable image.
*
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.

View File

@ -20,7 +20,6 @@
#include <stddef.h>
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_spi_flash.h"
#ifdef __cplusplus
extern "C"
@ -133,7 +132,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
*
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
* returned partition contains a bootable image.
*
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.

View File

@ -116,7 +116,7 @@ typedef union {
struct a2d_audio_cfg_param {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */
} audio_cfg; /*!< media codec configuration infomation */
} audio_cfg; /*!< media codec configuration information */
/**
* @brief ESP_A2D_MEDIA_CTRL_ACK_EVT
@ -147,12 +147,12 @@ typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len);
/**
* @brief A2DP source data read callback function
*
* @param[in] buf : buffer to be filled with PCM data stream from higer layer
* @param[in] buf : buffer to be filled with PCM data stream from higher layer
*
* @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user
* that data buffer shall be flushed
*
* @return size of bytes read successfully, if the argumetn len is -1, this value is ignored.
* @return size of bytes read successfully, if the argument len is -1, this value is ignored.
*
*/
typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len);

View File

@ -111,7 +111,7 @@ typedef enum {
/// AVRC shuffle modes
typedef enum {
ESP_AVRC_PS_SHUFFLE_OFF = 0x1, /*<! shuffle off */
ESP_AVRC_PS_SHUFFLE_ALL = 0x2, /*<! all trackes shuffle */
ESP_AVRC_PS_SHUFFLE_ALL = 0x2, /*<! shuffle all tracks */
ESP_AVRC_PS_SHUFFLE_GROUP = 0x3 /*<! group shuffle */
} esp_avrc_ps_shf_value_ids_t;

View File

@ -112,7 +112,7 @@ typedef enum {
BLE_ADDR_TYPE_RPA_RANDOM = 0x03,
} esp_ble_addr_type_t;
/// Used to exchange the encrytyption key in the init key & response key
/// Used to exchange the encryption key in the init key & response key
#define ESP_BLE_ENC_KEY_MASK (1 << 0) /* relate to BTM_BLE_ENC_KEY_MASK in stack/btm_api.h */
/// Used to exchange the IRK key in the init key & response key
#define ESP_BLE_ID_KEY_MASK (1 << 1) /* relate to BTM_BLE_ID_KEY_MASK in stack/btm_api.h */

View File

@ -151,7 +151,7 @@ typedef enum {
ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, /*!< When stop scan complete, the event comes */
ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, /*!< When set the static rand address complete, the event comes */
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt length complete, the event comes */
ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */
ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */
ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT, /*!< When clear the bond device clear complete, the event comes */
@ -264,6 +264,9 @@ typedef enum {
ESP_BLE_SM_SET_INIT_KEY,
ESP_BLE_SM_SET_RSP_KEY,
ESP_BLE_SM_MAX_KEY_SIZE,
ESP_BLE_SM_SET_STATIC_PASSKEY,
ESP_BLE_SM_CLEAR_STATIC_PASSKEY,
ESP_BLE_SM_MAX_PARAM,
} esp_ble_sm_param_t;
/// Advertising parameters
@ -455,7 +458,7 @@ typedef union
} esp_ble_key_value_t; /*!< ble key value type*/
/**
* @brief struct type of the bond key informatuon value
* @brief struct type of the bond key information value
*/
typedef struct
{
@ -508,7 +511,7 @@ typedef struct
uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
esp_bt_dev_type_t dev_type; /*!< Device type */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */
/**
* @brief union associated with ble security
@ -520,7 +523,7 @@ typedef union
esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */
esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */
esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */
} esp_ble_sec_t; /*!< Ble secutity type */
} esp_ble_sec_t; /*!< BLE security type */
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
typedef enum {
@ -1023,10 +1026,10 @@ esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept);
esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_act);
/**
* @brief Reply the key value to the peer device in the lagecy connection stage.
* @brief Reply the key value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer
* @param[in] accept : passkey entry sucessful or declined.
* @param[in] accept : passkey entry successful or declined.
* @param[in] passkey : passkey value, must be a 6 digit number,
* can be lead by 0.
*
@ -1038,7 +1041,7 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
/**
* @brief Reply the comfirm value to the peer device in the lagecy connection stage.
* @brief Reply the confirm value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer device
* @param[in] accept : numbers to compare are the same or different.
@ -1091,7 +1094,7 @@ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_lis
/**
* @brief This function is to disconnect the physical connection of the peer device
* gattc maybe have multiple virtual GATT server connections when multiple app_id registed.
* gattc may have multiple virtual GATT server connections when multiple app_id registered.
* esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id) only close one virtual GATT server connection.
* if there exist other virtual GATT server connections, it does not disconnect the physical connection.
* esp_ble_gap_disconnect(esp_bd_addr_t remote_device) disconnect the physical connection directly.

View File

@ -70,7 +70,7 @@ typedef enum {
typedef struct {
esp_bt_gap_dev_prop_type_t type; /*!< device property type */
int len; /*!< device property value length */
void *val; /*!< devlice prpoerty value */
void *val; /*!< device property value */
} esp_bt_gap_dev_prop_t;
/// Extended Inquiry Response data type
@ -97,11 +97,31 @@ typedef enum {
ESP_BT_COD_SRVC_RENDERING = 0x20, /*!< Rendering, e.g. Printing, Speakers */
ESP_BT_COD_SRVC_CAPTURING = 0x40, /*!< Capturing, e.g. Scanner, Microphone */
ESP_BT_COD_SRVC_OBJ_TRANSFER = 0x80, /*!< Object Transfer, e.g. v-Inbox, v-Folder */
ESP_BT_COD_SRVC_AUDIO = 0x100, /*!< Audio, e.g. Speaker, Microphone, Headerset service */
ESP_BT_COD_SRVC_AUDIO = 0x100, /*!< Audio, e.g. Speaker, Microphone, Headset service */
ESP_BT_COD_SRVC_TELEPHONY = 0x200, /*!< Telephony, e.g. Cordless telephony, Modem, Headset service */
ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */
} esp_bt_cod_srvc_t;
typedef enum{
ESP_BT_PIN_TYPE_VARIABLE = 0, /*!< Refer to BTM_PIN_TYPE_VARIABLE */
ESP_BT_PIN_TYPE_FIXED = 1, /*!< Refer to BTM_PIN_TYPE_FIXED */
} esp_bt_pin_type_t;
#define ESP_BT_PIN_CODE_LEN 16 /*!< Max pin code length */
typedef uint8_t esp_bt_pin_code_t[ESP_BT_PIN_CODE_LEN]; /*!< Pin Code (upto 128 bits) MSB is 0 */
typedef enum {
ESP_BT_SP_IOCAP_MODE = 0, /*!< Set IO mode */
//ESP_BT_SP_OOB_DATA, //TODO /*!< Set OOB data */
} esp_bt_sp_param_t;
/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
typedef uint8_t esp_bt_io_cap_t; /*!< combination of the io capability */
/// Bits of major service class field
#define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */
#define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */
@ -149,6 +169,10 @@ typedef enum {
ESP_BT_GAP_RMT_SRVCS_EVT, /*!< get remote services event */
ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< get remote service record event */
ESP_BT_GAP_AUTH_CMPL_EVT, /*!< AUTH complete event */
ESP_BT_GAP_PIN_REQ_EVT, /*!< Legacy Pairing Pin code request */
ESP_BT_GAP_CFM_REQ_EVT, /*!< Simple Pairing User Confirmation request. */
ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Simple Pairing Passkey Notification */
ESP_BT_GAP_KEY_REQ_EVT, /*!< Simple Pairing Passkey request */
ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< read rssi event */
ESP_BT_GAP_EVT_MAX,
} esp_bt_gap_cb_event_t;
@ -172,7 +196,7 @@ typedef union {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
int num_prop; /*!< number of properties got */
esp_bt_gap_dev_prop_t *prop; /*!< properties discovered from the new device */
} disc_res; /*!< discovery result paramter struct */
} disc_res; /*!< discovery result parameter struct */
/**
* @brief ESP_BT_GAP_DISC_STATE_CHANGED_EVT
@ -216,6 +240,37 @@ typedef union {
esp_bt_status_t stat; /*!< authentication complete status */
uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */
} auth_cmpl; /*!< authentication complete parameter struct */
/**
* @brief ESP_BT_GAP_PIN_REQ_EVT
*/
struct pin_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
bool min_16_digit; /*!< TRUE if the pin returned must be at least 16 digits */
} pin_req; /*!< pin request parameter struct */
/**
* @brief ESP_BT_GAP_CFM_REQ_EVT
*/
struct cfm_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
uint32_t num_val; /*!< the numeric value for comparison. */
} cfm_req; /*!< confirm request parameter struct */
/**
* @brief ESP_BT_GAP_KEY_NOTIF_EVT
*/
struct key_notif_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
uint32_t passkey; /*!< the numeric value for passkey entry. */
} key_notif; /*!< passkey notif parameter struct */
/**
* @brief ESP_BT_GAP_KEY_REQ_EVT
*/
struct key_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
} key_req; /*!< passkey request parameter struct */
} esp_bt_gap_cb_param_t;
/**
@ -447,6 +502,85 @@ int esp_bt_gap_get_bond_device_num(void);
*/
esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list);
/**
* @brief Set pin type and default pin code for legacy pairing.
*
* @param[in] pin_type: Use variable or fixed pin.
* If pin_type is ESP_BT_PIN_TYPE_VARIABLE, pin_code and pin_code_len
* will be ignored, and ESP_BT_GAP_PIN_REQ_EVT will come when control
* requests for pin code.
* Else, will use fixed pin code and not callback to users.
* @param[in] pin_code_len: Length of pin_code
* @param[in] pin_code: Pin_code
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*/
esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code);
/**
* @brief Reply the pin_code to the peer device for legacy pairing
* when ESP_BT_GAP_PIN_REQ_EVT is coming.
*
* @param[in] bd_addr: BD address of the peer
* @param[in] accept: Pin_code reply successful or declined.
* @param[in] pin_code_len: Length of pin_code
* @param[in] pin_code: Pin_code
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*/
esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code);
#if (BT_SSP_INCLUDED == TRUE)
/**
* @brief Set a GAP security parameter value. Overrides the default value.
*
* @param[in] param_type : the type of the param which is to be set
* @param[in] value : the param value
* @param[in] len : the length of the param value
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
void *value, uint8_t len);
/**
* @brief Reply the key value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer
* @param[in] accept : passkey entry successful or declined.
* @param[in] passkey : passkey value, must be a 6 digit number,
* can be lead by 0.
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey);
/**
* @brief Reply the confirm value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer device
* @param[in] accept : numbers to compare are the same or different.
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
#endif /*(BT_SSP_INCLUDED == TRUE)*/
#ifdef __cplusplus
}
#endif

View File

@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __ESP_GATT_COMMON_API_H__
#define __ESP_GATT_COMMON_API_H__
#include <stdint.h>
#include <stdbool.h>
@ -44,3 +47,5 @@ extern esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_GATT_COMMON_API_H__ */

View File

@ -224,7 +224,7 @@ typedef enum {
ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */ /* relate to BTA_GATT_CONN_L2C_FAILURE in bta/bta_gatt_api.h */
ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */ /* relate to BTA_GATT_CONN_TIMEOUT in bta/bta_gatt_api.h */
ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */ /* relate to BTA_GATT_CONN_TERMINATE_PEER_USER in bta/bta_gatt_api.h */
ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */ /* relate to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta/bta_gatt_api.h */
ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connection terminated by local host */ /* relate to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta/bta_gatt_api.h */
ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */ /* relate to BTA_GATT_CONN_FAIL_ESTABLISH in bta/bta_gatt_api.h */
ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */ /* relate to BTA_GATT_CONN_LMP_TIMEOUT in bta/bta_gatt_api.h */
ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */ /* relate to BTA_GATT_CONN_CONN_CANCEL in bta/bta_gatt_api.h */
@ -422,7 +422,7 @@ typedef struct {
* @brief service element
*/
typedef struct {
bool is_primary; /*!< The service flag, ture if the service is primary service, else is secondly service */
bool is_primary; /*!< The service flag, true if the service is primary service, else is secondly service */
uint16_t start_handle; /*!< The start handle of the service */
uint16_t end_handle; /*!< The end handle of the service */
esp_bt_uuid_t uuid; /*!< The uuid of the service */
@ -453,7 +453,7 @@ typedef struct {
uint16_t incl_srvc_s_handle; /*!< The start handle of the service which has been included */
uint16_t incl_srvc_e_handle; /*!< The end handle of the service which has been included */
esp_bt_uuid_t uuid; /*!< The include service uuid */
} esp_gattc_incl_svc_elem_t; /*!< The gattc inclue service element */
} esp_gattc_incl_svc_elem_t; /*!< The gattc include service element */
#ifdef __cplusplus

View File

@ -312,7 +312,7 @@ esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, e
/**
* @brief Close a virtual connection to a GATT server. gattc maybe have multiple virtual GATT server connections when multiple app_id registed,
* @brief Close the virtual connection to the GATT server. gattc may have multiple virtual GATT server connections when multiple app_id registered,
* this API only close one virtual GATT server connection. if there exist other virtual GATT server connections,
* it does not disconnect the physical connection.
* if you want to disconnect the physical connection directly, you can use esp_ble_gap_disconnect(esp_bd_addr_t remote_device).
@ -371,7 +371,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id: connection ID which identify the server.
* @param[in] svc_uuid: the pointer to the service uuid.
* @param[out] result: The pointer to the service whith has been found in the gattc cache.
* @param[out] result: The pointer to the service which has been found in the gattc cache.
* @param[inout] count: input the number of service want to find,
* it will output the number of service has been found in the gattc cache with the given service uuid.
* @param[in] offset: Offset of the service position to get.
@ -392,7 +392,7 @@ esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t con
* @param[in] conn_id: connection ID which identify the server.
* @param[in] start_handle: the attribute start handle.
* @param[in] end_handle: the attribute end handle
* @param[out] result: The pointer to the charateristic in the service.
* @param[out] result: The pointer to the characteristic in the service.
* @param[inout] count: input the number of characteristic want to find,
* it will output the number of characteristic has been found in the gattc cache with the given service.
* @param[in] offset: Offset of the characteristic position to get.
@ -695,7 +695,7 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] handle : charateristic handle to prepare write.
* @param[in] handle : characteristic handle to prepare write.
* @param[in] offset : offset of the write value.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.
@ -720,7 +720,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID.
* @param[in] handle : characteristic descriptor hanlde to prepare write.
* @param[in] handle : characteristic descriptor handle to prepare write.
* @param[in] offset : offset of the write value.
* @param[in] value_len: length of the value to be written.
* @param[in] value : the value to be written.

View File

@ -350,7 +350,8 @@ esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db
uint8_t max_nb_attr,
uint8_t srvc_inst_id);
/**
* @brief This function is called to add an included service. After included
* @brief This function is called to add an included service. This function have to be called between
* 'esp_ble_gatts_create_service' and 'esp_ble_gatts_add_char'. After included
* service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
* is reported the included service ID.
*

View File

@ -40,7 +40,7 @@ typedef enum {
ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */
ESP_HF_CLIENT_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED, /*!< audio connection is established */
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is estalibshed */
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */
} esp_hf_client_audio_state_t;
/// in-band ring tone state
@ -66,9 +66,9 @@ typedef enum {
#define ESP_HF_CLIENT_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */
#define ESP_HF_CLIENT_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */
#define ESP_HF_CLIENT_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */
#define ESP_HF_CLIENT_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold */
#define ESP_HF_CLIENT_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */
#define ESP_HF_CLIENT_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */
#define ESP_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnct from multiparty */
#define ESP_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */
/// HF CLIENT callback events
typedef enum {
@ -140,7 +140,7 @@ typedef union {
* @brief ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT
*/
struct hf_client_signal_strength_ind_param {
int value; /*!< singal strength value, ranges from 0 to 5 */
int value; /*!< signal strength value, ranges from 0 to 5 */
} signal_strength; /*!< HF callback param of ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT */
/**
@ -175,7 +175,7 @@ typedef union {
* @brief ESP_HF_CLIENT_CIND_CALL_HELD_EVT
*/
struct hf_client_call_held_ind_param {
esp_hf_call_held_status_t status; /*!< bluetooth proprietary call hold status indocator */
esp_hf_call_held_status_t status; /*!< bluetooth proprietary call hold status indicator */
} call_held; /*!< HF callback param of ESP_HF_CLIENT_CIND_CALL_HELD_EVT */
/**
@ -619,7 +619,7 @@ void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t c
* @brief Down sampling utility to convert high sampling rate into 8K/16bits 1-channel mode PCM
* samples. This can only be used in the case that Voice Over HCI is enabled.
*
* @param[in] src: pointer to the buffer where the original smapling PCM are stored
* @param[in] src: pointer to the buffer where the original sampling PCM are stored
* @param[in] in_bytes: length of the input PCM sample buffer in byte
* @param[in] dst: pointer to the buffer which is to be used to store the converted PCM samples
*

View File

@ -120,7 +120,7 @@ typedef enum {
/// response indication codes for AT commands
typedef enum {
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknoweledges execution of a command line */
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */
ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */
ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */
ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */

View File

@ -62,9 +62,9 @@ typedef enum {
ESP_SPP_CLOSE_EVT = 27, /*!< When SPP connection closed, the event comes */
ESP_SPP_START_EVT = 28, /*!< When SPP server started, the event comes */
ESP_SPP_CL_INIT_EVT = 29, /*!< When SPP client initiated a connection, the event comes */
ESP_SPP_DATA_IND_EVT = 30, /*!< When SPP connection received data, the event comes, olny for ESP_SPP_MODE_CB */
ESP_SPP_CONG_EVT = 31, /*!< When SPP connection congestion status changed, the event comes, olny for ESP_SPP_MODE_CB */
ESP_SPP_WRITE_EVT = 33, /*!< When SPP write operation completes, the event comes, olny for ESP_SPP_MODE_CB */
ESP_SPP_DATA_IND_EVT = 30, /*!< When SPP connection received data, the event comes, only for ESP_SPP_MODE_CB */
ESP_SPP_CONG_EVT = 31, /*!< When SPP connection congestion status changed, the event comes, only for ESP_SPP_MODE_CB */
ESP_SPP_WRITE_EVT = 33, /*!< When SPP write operation completes, the event comes, only for ESP_SPP_MODE_CB */
ESP_SPP_SRV_OPEN_EVT = 34, /*!< When SPP Server connection open, the event comes */
} esp_spp_cb_event_t;
@ -95,7 +95,7 @@ typedef union {
struct spp_open_evt_param {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
int fd; /*!< The file descriptor olny for ESP_SPP_MODE_VFS*/
int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */
esp_bd_addr_t rem_bda; /*!< The peer address */
} open; /*!< SPP callback param of ESP_SPP_OPEN_EVT */
@ -106,7 +106,7 @@ typedef union {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint32_t new_listen_handle; /*!< The new listen handle */
int fd; /*!< The file descriptor olny for ESP_SPP_MODE_VFS*/
int fd; /*!< The file descriptor only for ESP_SPP_MODE_VFS */
esp_bd_addr_t rem_bda; /*!< The peer address */
} srv_open; /*!< SPP callback param of ESP_SPP_SRV_OPEN_EVT */
/**
@ -155,7 +155,7 @@ typedef union {
esp_spp_status_t status; /*!< status */
uint32_t handle; /*!< The connection handle */
uint16_t len; /*!< The length of data */
uint8_t *data; /*!< The data recived */
uint8_t *data; /*!< The data received */
} data_ind; /*!< SPP callback param of ESP_SPP_DATA_IND_EVT */
/**
@ -224,14 +224,14 @@ esp_err_t esp_spp_deinit();
esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
/**
* @brief This function makes an SPP conection to a remote BD Address.
* @brief This function makes an SPP connection to a remote BD Address.
* When the connection is initiated or failed to initiate,
* the callback is called with ESP_SPP_CL_INIT_EVT.
* When the connection is established or failed,
* the callback is called with ESP_SPP_OPEN_EVT.
*
* @param[in] sec_mask: Security Setting Mask .
* @param[in] role: Msater or slave.
* @param[in] role: Master or slave.
* @param[in] remote_scn: Remote device bluetooth device SCN.
* @param[in] peer_bd_addr: Remote device bluetooth device address.
*
@ -262,7 +262,7 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
* with ESP_SPP_SRV_OPEN_EVT.
*
* @param[in] sec_mask: Security Setting Mask .
* @param[in] role: Msater or slave.
* @param[in] role: Master or slave.
* @param[in] local_scn: The specific channel you want to get.
* If channel is 0, means get any channel.
* @param[in] name: Server's name.
@ -276,7 +276,7 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
/**
* @brief This function is used to write data, olny for ESP_SPP_MODE_CB.
* @brief This function is used to write data, only for ESP_SPP_MODE_CB.
*
* @param[in] handle: The connection handle.
* @param[in] len: The length of the data written.
@ -302,4 +302,4 @@ esp_err_t esp_spp_vfs_register(void);
}
#endif
#endif ///__ESP_SPP_API_H__
#endif ///__ESP_SPP_API_H__

View File

@ -631,10 +631,13 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */
#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */
// btla-specific --
#define BTA_DM_DEV_UNPAIRED_EVT 25
#define BTA_DM_DEV_UNPAIRED_EVT 25 /* BT unpair event */
#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */
#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */
#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
#define BTA_DM_BLE_DEV_UNPAIRED_EVT 29 /* BLE unpair event */
#define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */
typedef UINT8 tBTA_DM_SEC_EVT;
/* Structure associated with BTA_DM_ENABLE_EVT */
@ -867,6 +870,13 @@ typedef struct {
tBTA_AUTH_REQ rmt_io_caps; /* IO Capabilities of remote device */
} tBTA_DM_SP_CFM_REQ;
/* Structure associated with tBTA_DM_SP_KEY_REQ */
typedef struct {
BD_ADDR bd_addr; /* peer address */
DEV_CLASS dev_class; /* peer CoD */
BD_NAME bd_name; /* peer device name */
} tBTA_DM_SP_KEY_REQ;
enum {
BTA_SP_KEY_STARTED, /* passkey entry started */
BTA_SP_KEY_ENTERED, /* passkey digit entered */
@ -906,23 +916,24 @@ typedef struct {
/* Union of all security callback structures */
typedef union {
tBTA_DM_ENABLE enable; /* BTA enabled */
tBTA_DM_PIN_REQ pin_req; /* PIN request. */
tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */
tBTA_DM_AUTHORIZE authorize; /* Authorization request. */
tBTA_DM_LINK_UP link_up; /* ACL connection down event */
tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */
tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */
tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */
tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */
tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */
tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */
tBTA_DM_ROLE_CHG role_chg; /* role change event */
tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */
tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */
tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */
BT_OCTET16 ble_er; /* ER event data */
tBTA_DM_ENABLE enable; /* BTA enabled */
tBTA_DM_PIN_REQ pin_req; /* PIN request. */
tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */
tBTA_DM_AUTHORIZE authorize; /* Authorization request. */
tBTA_DM_LINK_UP link_up; /* ACL connection down event */
tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */
tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */
tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */
tBTA_DM_SP_KEY_REQ key_req; /* user passkey request */
tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */
tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */
tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */
tBTA_DM_ROLE_CHG role_chg; /* role change event */
tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */
tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */
tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */
BT_OCTET16 ble_er; /* ER event data */
} tBTA_DM_SEC;
/* Security callback */
@ -1559,6 +1570,18 @@ extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport);
*******************************************************************************/
extern void BTA_DmBondCancel(BD_ADDR bd_addr);
/*******************************************************************************
**
** Function BTA_DMSetPinType
**
** Description This function sets pin type as BTM_PIN_TYPE_FIXED or BTM_PIN_TYPE_VARIABLE
**
**
** Returns void
**
*******************************************************************************/
extern void BTA_DMSetPinType (UINT8 pin_type, UINT8 *pin_code, UINT8 pin_code_len);
/*******************************************************************************
**
** Function BTA_DmPinReply
@ -1601,6 +1624,18 @@ extern void BTA_DmLocalOob(void);
*******************************************************************************/
extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept);
/*******************************************************************************
**
** Function BTA_DmPasskeyReqReply
**
** Description This function is called to provide the passkey for
** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
**
** Returns void
**
*******************************************************************************/
extern void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey);
/*******************************************************************************
**
** Function BTA_DmAddDevice
@ -1632,7 +1667,7 @@ extern void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class,
** BTA_FAIL if operation failed.
**
*******************************************************************************/
extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr);
extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport);
/*******************************************************************************
**
@ -1789,6 +1824,22 @@ extern void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_B
*******************************************************************************/
extern void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, BOOLEAN accept, UINT32 passkey);
/*******************************************************************************
**
** Function BTA_DmBleSetStaticPasskey
**
** Description Set BLE SMP static passkey.
**
** Parameters: add - add static passkey when add is true
** clear static passkey when add is false
** passkey - static passkey value
**
**
** Returns void
**
*******************************************************************************/
extern void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey);
/*******************************************************************************
**
** Function BTA_DmBleConfirmReply

View File

@ -98,7 +98,7 @@ typedef UINT8 tBTA_AV_HNDL;
#endif
#ifndef BTA_AV_MAX_SEPS
#define BTA_AV_MAX_SEPS 2
#define BTA_AV_MAX_SEPS 1
#endif
#ifndef BTA_AV_MAX_A2DP_MTU
@ -259,7 +259,7 @@ typedef UINT8 tBTA_AV_ERR;
/* function types for call-out functions */
typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep);
typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
@ -580,7 +580,7 @@ void BTA_AvDisable(void);
**
*******************************************************************************/
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name,
UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos);
UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep);
/*******************************************************************************
**

View File

@ -85,7 +85,7 @@ typedef struct {
**
*******************************************************************************/
extern BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info,
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep);
/*******************************************************************************
**

View File

@ -30,6 +30,20 @@
** Function Declarations
*****************************************************************************/
/*******************************************************************************
**
** Function bta_dm_co_bt_set_io_cap
**
** Description This function is used to set IO capabilities
**
** Parameters bt_io_cap - IO capabilities
**
** @return - ESP_BT_STATUS_SUCCESS : success
** - other : failed
**
*******************************************************************************/
extern esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap);
/*******************************************************************************
**
** Function bta_dm_co_io_req

View File

@ -55,7 +55,7 @@ extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RAN
**
** Returns TRUE - if the request is processed successfully and
** the response is returned in p_rsp.
** FASLE - if the request can not be processed
** FALSE - if the request can not be processed
**
*******************************************************************************/
extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,

View File

@ -28,6 +28,11 @@ typedef struct btc_msg {
void *arg; //param for btc function or function param
} btc_msg_t;
typedef struct btc_adv_packet {
uint8_t addr[6];
uint8_t addr_type;
} btc_adv_packet_t;
typedef enum {
BTC_SIG_API_CALL = 0, // APP TO STACK
BTC_SIG_API_CB, // STACK TO APP
@ -72,5 +77,6 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
int btc_init(void);
void btc_deinit(void);
bool btc_check_queue_is_congest(void);
#endif /* __BTC_TASK_H__ */

View File

@ -166,5 +166,7 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_callback_init(void);
void btc_gap_ble_deinit(void);
void btc_adv_list_init(void);
void btc_adv_list_deinit(void);
#endif /* __BTC_GAP_BLE_H__ */

View File

@ -26,8 +26,12 @@ typedef enum {
BTC_GAP_BT_SEARCH_DEVICES_EVT = 0,
BTC_GAP_BT_SEARCH_SERVICES_EVT,
BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT,
BTC_GAP_BT_READ_RSSI_DELTA_EVT,
BTC_GAP_BT_AUTH_CMPL_EVT,
BTC_GAP_BT_PIN_REQ_EVT,
BTC_GAP_BT_CFM_REQ_EVT,
BTC_GAP_BT_KEY_NOTIF_EVT,
BTC_GAP_BT_KEY_REQ_EVT,
BTC_GAP_BT_READ_RSSI_DELTA_EVT,
}btc_gap_bt_evt_t;
typedef enum {
@ -39,6 +43,11 @@ typedef enum {
BTC_GAP_BT_ACT_SET_COD,
BTC_GAP_BT_ACT_READ_RSSI_DELTA,
BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE,
BTC_GAP_BT_ACT_SET_PIN_TYPE,
BTC_GAP_BT_ACT_PIN_REPLY,
BTC_GAP_BT_ACT_SET_SECURITY_PARAM,
BTC_GAP_BT_ACT_PASSKEY_REPLY,
BTC_GAP_BT_ACT_CONFIRM_REPLY,
} btc_gap_bt_act_t;
/* btc_bt_gap_args_t */
@ -79,11 +88,46 @@ typedef union {
struct rm_bond_device_args {
bt_bdaddr_t bda;
} rm_bond_device;
// BTC_GAP_BT_ACT_SET_PIN_TYPE
struct set_pin_type_args {
esp_bt_pin_type_t pin_type;
uint8_t pin_code_len;
esp_bt_pin_code_t pin_code;
} set_pin_type;
// BTC_GAP_BT_ACT_PIN_REPLY
struct pin_reply_args {
bt_bdaddr_t bda;
bool accept;
uint8_t pin_code_len;
esp_bt_pin_code_t pin_code;
} pin_reply;
// BTC_GAP_BT_ACT_SET_SECURITY_PARAM
struct set_sec_param_args {
esp_bt_sp_param_t param_type;
uint8_t len;
uint8_t *value;
} set_security_param;
// BTC_GAP_BT_ACT_PASSKEY_REPLY
struct passkey_reply_args {
bt_bdaddr_t bda;
bool accept;
uint32_t passkey;
} passkey_reply;
// BTC_GAP_BT_ACT_CONFIRM_REPLY
struct confirm_reply_args {
bt_bdaddr_t bda;
bool accept;
} confirm_reply;
} btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg);
void btc_gap_bt_cb_handler(btc_msg_t *msg);
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_bt_busy_level_updated(uint8_t bl_flags);
esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod);

View File

@ -26,9 +26,6 @@
#define UNUSED(x) (void)(x)
#ifndef SIZE_MAX
#define SIZE_MAX 254
#endif
/*Timer Related Defination*/
//by Snake.T

View File

@ -52,6 +52,7 @@
#define BTA_SDP_INCLUDED TRUE
#define BTA_DM_PM_INCLUDED TRUE
#define SDP_INCLUDED TRUE
#define BT_SSP_INCLUDED TRUE
#if CONFIG_A2DP_ENABLE
#define BTA_AR_INCLUDED TRUE
@ -127,7 +128,7 @@
#else
#define SMP_INCLUDED FALSE
#define BLE_PRIVACY_SPT FALSE
#endif /* CONFIG_GATTC_ENABLE */
#endif /* CONFIG_SMP_ENABLE */
#if (CONFIG_BT_ACL_CONNECTIONS)
#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS
@ -307,6 +308,16 @@
#define BTA_AV_CO_CP_SCMS_T FALSE//FALSE
#endif
#ifndef QUEUE_CONGEST_SIZE
#define QUEUE_CONGEST_SIZE 40
#endif
#ifndef CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
#define SCAN_QUEUE_CONGEST_CHECK FALSE
#else
#define SCAN_QUEUE_CONGEST_CHECK CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
#endif
/* This feature is used to eanble interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE
@ -981,7 +992,7 @@
#endif
#ifndef BTM_BLE_ADV_TX_POWER
#define BTM_BLE_ADV_TX_POWER {-21, -15, -7, 1, 9}
#define BTM_BLE_ADV_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9}
#endif
@ -1145,6 +1156,20 @@
#define SMP_LINK_TOUT_MIN 2
#endif
#endif
/******************************************************************************
**
** BT_SSP
**
******************************************************************************/
#ifndef BT_SSP_INCLUDED
#define BT_SSP_INCLUDED FALSE
#endif
#if BT_SSP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == FALSE
#error "Can't have SSP without CLASSIC BT"
#endif
/******************************************************************************
**
** SDP

View File

@ -32,6 +32,18 @@ typedef struct {
UINT8 ble_resp_key;
UINT8 ble_max_key_size;
#endif
} tBTE_APPL_CFG;
extern tBTE_APPL_CFG bte_appl_cfg;
typedef struct {
#if ((CLASSIC_BT_INCLUDED == TRUE) && (BT_SSP_INCLUDED == TRUE))
UINT8 bt_auth_req;
UINT8 bt_io_cap;
UINT8 *bt_oob_auth_data;
#endif
} tBTE_BT_APPL_CFG;
extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;

View File

@ -25,83 +25,7 @@
extern "C" {
#endif
/**
* @brief Controller config options, depend on config mask.
* Config mask indicate which functions enabled, this means
* some options or parameters of some functions enabled by config mask.
*/
typedef struct {
uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint8_t scan_duplicate_mode; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
uint32_t controller_debug_flag; /*!< Controller debug log flag */
} esp_bt_controller_config_t;
#ifdef CONFIG_BT_ENABLED
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
#else
#define BT_HCI_UART_NO_DEFAULT 1
#endif /* BT_HCI_UART_NO_DEFAULT */
#ifdef CONFIG_BT_HCI_UART_BAUDRATE
#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
#else
#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
/* normal adv cache size */
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#else
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
#endif
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
#endif
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#else
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
#endif
#else
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
#endif
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
};
#else
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h");
#endif
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x5A5AA5A5
/**
* @brief Bluetooth mode for controller enable/disable
@ -113,6 +37,122 @@ typedef enum {
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
} esp_bt_mode_t;
#ifdef CONFIG_BT_ENABLED
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
#else
#define BT_HCI_UART_NO_DEFAULT 1
#endif /* BT_HCI_UART_NO_DEFAULT */
#ifdef CONFIG_BT_HCI_UART_BAUDRATE
#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
#else
#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
#ifdef CONFIG_SCAN_DUPLICATE_TYPE
#define SCAN_DUPLICATE_TYPE_VALUE CONFIG_SCAN_DUPLICATE_TYPE
#else
#define SCAN_DUPLICATE_TYPE_VALUE 0
#endif
/* normal adv cache size */
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#else
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
#endif
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
#endif
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#else
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
#endif
#else
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
#endif
#if defined(CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE
#elif defined(CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_CLASSIC_BT
#else
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BTDM
#endif
#define BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT 9 //Maximum BLE connection limitation
#define BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT 7 //Maximum ACL connection limitation
#define BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT 3 //Maximum SCO/eSCO connection limitation
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
.scan_duplicate_type = SCAN_DUPLICATE_TYPE_VALUE, \
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
.mode = BTDM_CONTROLLER_MODE_EFF, \
.ble_max_conn = CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF, \
.bt_max_acl_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF, \
.bt_max_sync_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF, \
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
};
#else
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h");
#endif
/**
* @brief Controller config options, depend on config mask.
* Config mask indicate which functions enabled, this means
* some options or parameters of some functions enabled by config mask.
*/
typedef struct {
/*
* Following parameters can be configured runtime, when call esp_bt_controller_init()
*/
uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint8_t scan_duplicate_mode; /*!< scan duplicate mode */
uint8_t scan_duplicate_type; /*!< scan duplicate type */
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
uint32_t controller_debug_flag; /*!< Controller debug log flag */
uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
uint8_t ble_max_conn; /*!< BLE maximum connection numbers */
uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */
/*
* Following parameters can not be configured runtime when call esp_bt_controller_init()
* It will be overwrite with a constant value which in menuconfig or from a macro.
* So, do not modify the value when esp_bt_controller_init()
*/
uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */
uint32_t magic; /*!< Magic number */
} esp_bt_controller_config_t;
/**
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
*/
@ -123,7 +163,6 @@ typedef enum {
ESP_BT_CONTROLLER_STATUS_NUM,
} esp_bt_controller_status_t;
/**
* @brief BLE tx power type
* ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed.
@ -202,7 +241,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
* BR/EDR power control will use the power in range of minimum value and maximum value.
* The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on.
* Please call the function after esp_bt_controller_enable and before any function which cause RF do TX.
* So you can call the function can before do discover, beofre profile init and so on.
* So you can call the function before doing discovery, profile init and so on.
* For example, if you want BR/EDR use the new TX power to do inquire, you should call
* this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING),
* please do inquire again after call this function.
@ -231,10 +270,11 @@ esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_l
esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path);
/**
* @brief Initialize BT controller to allocate task and other resource.
* @param cfg: Initial configuration of BT controller.
* This function should be called only once, before any other BT functions are called.
* @return ESP_OK - success, other - failed
* @brief Initialize BT controller to allocate task and other resource.
* This function should be called only once, before any other BT functions are called.
* @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some
* connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
@ -252,7 +292,8 @@ esp_err_t esp_bt_controller_deinit(void);
* Due to a known issue, you cannot call esp_bt_controller_enable() a second time
* to change the controller mode dynamically. To change controller mode, call
* esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.
* @param mode : the mode(BLE/BT/BTDM) to enable.
* @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be
* equal as the mode in "cfg" of esp_bt_controller_init().
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
@ -291,40 +332,70 @@ bool esp_vhci_host_check_send_available(void);
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
/** @brief esp_vhci_host_register_callback
* register the vhci referece callback, the call back
* register the vhci reference callback
* struct defined by vhci_host_callback structure.
* @param callback esp_vhci_host_callback type variable
* @return ESP_OK - success, ESP_FAIL - failed
*/
void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
/** @brief esp_bt_controller_mem_release
* release the memory by mode, if never use the bluetooth mode
* it can release the .bss, .data and other section to heap.
* The total size is about 70k bytes.
* release the controller memory as per the mode
*
* This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
*
* esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
* or after esp_bt_controller_deinit().
*
* Note that once BT controller memory is released, the process cannot be reversed. It means you can not use the bluetooth
* Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialisation time to free unused BT Classic memory.
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory.
*
* If user never use bluetooth controller, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)
* before esp_bt_controller_init or after esp_bt_controller_deinit.
*
* For example, user only use bluetooth to config SSID and PASSWORD of WIFI, after config, will never use bluetooth.
* Then, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) after esp_bt_controller_deinit.
* If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead,
* which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data
* consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of
* esp_bt_mem_release() function
*
* @param mode : the mode want to release memory
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
/** @brief esp_bt_mem_release
* release controller memory and BSS and data section of the BT/BLE host stack as per the mode
*
* This function first releases controller memory by internally calling esp_bt_controller_mem_release().
* Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap
*
* Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM)
* before esp_bt_controller_init or after esp_bt_controller_deinit.
*
* For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation".
* In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory.
* Below is the sequence of APIs to be called for such scenarios:
*
* esp_bluedroid_disable();
* esp_bluedroid_deinit();
* esp_bt_controller_disable();
* esp_bt_controller_deinit();
* esp_bt_mem_release(ESP_BT_MODE_BTDM);
*
* @param mode : the mode whose memory is to be released
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
/**
* @brief enable bluetooth to enter modem sleep
*
@ -377,10 +448,23 @@ bool esp_bt_controller_is_sleeping(void);
* Note that after this request, bluetooth controller may again enter sleep as long as the modem sleep is enabled
*
* Profiling shows that it takes several milliseconds to wakeup from modem sleep after this request.
* Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequncy of the former as the bluetooth low power clock source.
* Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequency of the former as the bluetooth low power clock source.
*/
void esp_bt_controller_wakeup_request(void);
/**
* @brief Manually clear scan duplicate list
*
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
* the amount of device in the filter can be configured in menuconfig.
*
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_scan_dupilcate_list_flush(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,25 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _BUFFER_ALLOCATOR_H_
#include "osi/allocator.h"
const allocator_t *buffer_allocator_get_interface();
#endif /*_BUFFER_ALLOCATOR_H_*/

View File

@ -44,6 +44,7 @@ typedef struct {
BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime);
BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask);
BT_HDR *(*make_write_sync_flow_control_enable)(uint8_t enable);
BT_HDR *(*make_write_default_erroneous_data_report)(uint8_t enable);
} hci_packet_factory_t;
const hci_packet_factory_t *hci_packet_factory_get_interface();

View File

@ -1,265 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "prf_defs.h"
#if (HIDD_LE_PROFILE_CFG)
#include "bta_gatts_int.h"
#include "stack/bt_types.h"
#include "bta/bta_api.h"
#include "stack/gatt_api.h"
#include "bt_app_api.h"
/// Maximal number of HIDS that can be added in the DB
#ifndef USE_ONE_HIDS_INSTANCE
#define HIDD_LE_NB_HIDS_INST_MAX (2)
#else
#define HIDD_LE_NB_HIDS_INST_MAX (1)
#endif
// Number of HID reports defined in the service
#define HID_NUM_REPORTS 9
#define ATT_SVC_HID 0x1812
/// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11
#define HIDD_LE_NB_REPORT_INST_MAX (5)
/// Maximal length of Report Char. Value
#define HIDD_LE_REPORT_MAX_LEN (45)
/// Maximal length of Report Map Char. Value
#define HIDD_LE_REPORT_MAP_MAX_LEN (512)
/// Length of Boot Report Char. Value Maximal Length
#define HIDD_LE_BOOT_REPORT_MAX_LEN (8)
/// Boot KB Input Report Notification Configuration Bit Mask
#define HIDD_LE_BOOT_KB_IN_NTF_CFG_MASK (0x40)
/// Boot KB Input Report Notification Configuration Bit Mask
#define HIDD_LE_BOOT_MOUSE_IN_NTF_CFG_MASK (0x80)
/// Boot Report Notification Configuration Bit Mask
#define HIDD_LE_REPORT_NTF_CFG_MASK (0x20)
/* HID information flags */
#define HID_FLAGS_REMOTE_WAKE 0x01 // RemoteWake
#define HID_FLAGS_NORMALLY_CONNECTABLE 0x02 // NormallyConnectable
/* Control point commands */
#define HID_CMD_SUSPEND 0x00 // Suspend
#define HID_CMD_EXIT_SUSPEND 0x01 // Exit Suspend
/* HID protocol mode values */
#define HID_PROTOCOL_MODE_BOOT 0x00 // Boot Protocol Mode
#define HID_PROTOCOL_MODE_REPORT 0x01 // Report Protocol Mode
/* Attribute value lengths */
#define HID_PROTOCOL_MODE_LEN 1 // HID Protocol Mode
#define HID_INFORMATION_LEN 4 // HID Information
#define HID_REPORT_REF_LEN 2 // HID Report Reference Descriptor
#define HID_EXT_REPORT_REF_LEN 2 // External Report Reference Descriptor
// HID feature flags
#define HID_KBD_FLAGS HID_FLAGS_REMOTE_WAKE
/// HID Service Attributes Indexes
enum {
HIDD_LE_IDX_SVC,
// Included Service
HIDD_LE_IDX_INCL_SVC,
// HID Information
HIDD_LE_IDX_HID_INFO_CHAR,
HIDD_LE_IDX_HID_INFO_VAL,
// HID Control Point
HIDD_LE_IDX_HID_CTNL_PT_CHAR,
HIDD_LE_IDX_HID_CTNL_PT_VAL,
// Report Map
HIDD_LE_IDX_REPORT_MAP_CHAR,
HIDD_LE_IDX_REPORT_MAP_VAL,
HIDD_LE_IDX_REPORT_MAP_EXT_REP_REF,
// Protocol Mode
HIDD_LE_IDX_PROTO_MODE_CHAR,
HIDD_LE_IDX_PROTO_MODE_VAL,
// Boot Keyboard Input Report
HIDD_LE_IDX_BOOT_KB_IN_REPORT_CHAR,
HIDD_LE_IDX_BOOT_KB_IN_REPORT_VAL,
HIDD_LE_IDX_BOOT_KB_IN_REPORT_NTF_CFG,
// Boot Keyboard Output Report
HIDD_LE_IDX_BOOT_KB_OUT_REPORT_CHAR,
HIDD_LE_IDX_BOOT_KB_OUT_REPORT_VAL,
// Boot Mouse Input Report
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_CHAR,
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_VAL,
HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG,
// Report
HIDD_LE_IDX_REPORT_CHAR,
HIDD_LE_IDX_REPORT_VAL,
HIDD_LE_IDX_REPORT_REP_REF,
HIDD_LE_IDX_REPORT_NTF_CFG,
HIDD_LE_IDX_NB,
};
/// Attribute Table Indexes
enum {
HIDD_LE_INFO_CHAR,
HIDD_LE_CTNL_PT_CHAR,
HIDD_LE_REPORT_MAP_CHAR,
HIDD_LE_REPORT_CHAR,
HIDD_LE_PROTO_MODE_CHAR,
HIDD_LE_BOOT_KB_IN_REPORT_CHAR,
HIDD_LE_BOOT_KB_OUT_REPORT_CHAR,
HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR,
HIDD_LE_CHAR_MAX //= HIDD_LE_REPORT_CHAR + HIDD_LE_NB_REPORT_INST_MAX,
};
///att read event table Indexs
enum {
HIDD_LE_READ_INFO_EVT,
HIDD_LE_READ_CTNL_PT_EVT,
HIDD_LE_READ_REPORT_MAP_EVT,
HIDD_LE_READ_REPORT_EVT,
HIDD_LE_READ_PROTO_MODE_EVT,
HIDD_LE_BOOT_KB_IN_REPORT_EVT,
HIDD_LE_BOOT_KB_OUT_REPORT_EVT,
HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT,
HID_LE_EVT_MAX
};
/// Client Characteristic Configuration Codes
enum {
HIDD_LE_DESC_MASK = 0x10,
HIDD_LE_BOOT_KB_IN_REPORT_CFG = HIDD_LE_BOOT_KB_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
HIDD_LE_BOOT_MOUSE_IN_REPORT_CFG = HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
HIDD_LE_REPORT_CFG = HIDD_LE_REPORT_CHAR | HIDD_LE_DESC_MASK,
};
/// Features Flag Values
enum {
HIDD_LE_CFG_KEYBOARD = 0x01,
HIDD_LE_CFG_MOUSE = 0x02,
HIDD_LE_CFG_PROTO_MODE = 0x04,
HIDD_LE_CFG_MAP_EXT_REF = 0x08,
HIDD_LE_CFG_BOOT_KB_WR = 0x10,
HIDD_LE_CFG_BOOT_MOUSE_WR = 0x20,
};
/// Report Char. Configuration Flag Values
enum {
HIDD_LE_CFG_REPORT_IN = 0x01,
HIDD_LE_CFG_REPORT_OUT = 0x02,
//HOGPD_CFG_REPORT_FEAT can be used as a mask to check Report type
HIDD_LE_CFG_REPORT_FEAT = 0x03,
HIDD_LE_CFG_REPORT_WR = 0x10,
};
/// Pointer to the connection clean-up function
#define HIDD_LE_CLEANUP_FNCT (NULL)
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// HIDD Features structure
typedef struct {
/// Service Features
uint8_t svc_features;
/// Number of Report Char. instances to add in the database
uint8_t report_nb;
/// Report Char. Configuration
uint8_t report_char_cfg[HIDD_LE_NB_REPORT_INST_MAX];
} hidd_feature_t;
typedef struct {
BOOLEAN in_use;
BOOLEAN congest;
uint16_t conn_id;
BOOLEAN connected;
BD_ADDR remote_bda;
uint32_t trans_id;
uint8_t cur_srvc_id;
} hidd_clcb_t;
// HID report mapping table
typedef struct {
uint16_t handle; // Handle of report characteristic
uint16_t cccdHandle; // Handle of CCCD for report characteristic
uint8_t id; // Report ID
uint8_t type; // Report type
uint8_t mode; // Protocol mode (report or boot)
} hidRptMap_t;
typedef struct {
/// hidd profile id
uint8_t app_id;
/// Notified handle
uint16_t ntf_handle;
///Attribute handle Table
uint16_t att_tbl[HIDD_LE_CHAR_MAX];
/// Supported Features
hidd_feature_t hidd_feature[HIDD_LE_NB_HIDS_INST_MAX];
/// Current Protocol Mode
uint8_t proto_mode[HIDD_LE_NB_HIDS_INST_MAX];
/// Number of HIDS added in the database
uint8_t hids_nb;
uint8_t pending_evt;
uint16_t pending_hal;
} hidd_inst_t;
/* service engine control block */
typedef struct {
hidd_clcb_t hidd_clcb; /* connection link*/
esp_gatt_if_t gatt_if;
BOOLEAN enabled;
BOOLEAN is_primery;
hidd_inst_t hidd_inst;
uint8_t inst_id;
} hidd_le_env_t;
extern hidd_le_env_t hidd_le_env;
void hidd_le_create_service(BOOLEAN is_primary);
void hidd_rsp (uint32_t trans_id, uint16_t conn_id, uint8_t app_id,
esp_gatt_status_t status, uint8_t event, tGATTS_DATA *p_rsp);
void hidd_read_attr_value(tGATTS_DATA *p_data, uint32_t trans_id);
tGATT_STATUS hidd_le_init (void);
#endif ///HIDD_LE_PROFILE_CFG

View File

@ -24,18 +24,6 @@
#include "esp_heap_caps.h"
#include "sdkconfig.h"
typedef void *(*alloc_fn)(size_t size);
typedef void (*free_fn)(void *ptr);
typedef struct {
alloc_fn alloc;
free_fn free;
} allocator_t;
// allocator_t abstractions for the osi_*alloc and osi_free functions
extern const allocator_t allocator_malloc;
extern const allocator_t allocator_calloc;
char *osi_strdup(const char *str);
void *osi_malloc_func(size_t size);

View File

@ -22,6 +22,10 @@
#include <stdbool.h>
#include "osi/list.h"
#ifndef QUEUE_SIZE_MAX
#define QUEUE_SIZE_MAX 254
#endif
struct fixed_queue_t;
typedef struct fixed_queue_t fixed_queue_t;

View File

@ -69,7 +69,7 @@ typedef enum {
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
#define HCI_H4_TASK_NAME "hciH4T"
#define HCI_H4_QUEUE_LEN 60
#define HCI_H4_QUEUE_LEN 1
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTU_TASK_STACK_SIZE (4096 + BT_TASK_EXTRA_STACK_SIZE)

View File

@ -58,6 +58,8 @@ extern elliptic_curve_t curve_p256;
void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
bool ECC_CheckPointIsInElliCur_P256(Point *p);
#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength)
void p_256_init_curve(UINT32 keyLength);

View File

@ -132,6 +132,8 @@ typedef UINT8 tSMP_EVENT;
/* Assumption it's only using the low 8 bits, if bigger than that, need to expand it to 16 bits */
#define SMP_SEC_KEY_MASK 0x00ff
#define SMP_PASSKEY_MASK 0xfff00000
/* SMP pairing state */
enum {
SMP_STATE_IDLE,
@ -331,6 +333,8 @@ typedef struct {
UINT8 rcvd_cmd_len;
UINT16 total_tx_unacked;
BOOLEAN wait_for_authorization_complete;
BOOLEAN use_static_passkey;
UINT32 static_passkey;
} tSMP_CB;
/* Server Action functions are of this type */

View File

@ -47,21 +47,21 @@
/* command type codes */
#define AVRC_CMD_CTRL 0 /* Instruct a target to perform an operation */
#define AVRC_CMD_STATUS 1 /* Check a devices current status */
#define AVRC_CMD_STATUS 1 /* Check a device’s current status */
#define AVRC_CMD_SPEC_INQ 2 /* Check whether a target supports a particular
control command; all operands are included */
#define AVRC_CMD_NOTIF 3 /* Used for receiving notification of a change in a devices state */
#define AVRC_CMD_NOTIF 3 /* Used for receiving notification of a change in a device’s state */
#define AVRC_CMD_GEN_INQ 4 /* Check whether a target supports a particular
control command; operands are not included */
/* response type codes */
#define AVRC_RSP_NOT_IMPL 8 /* The target does not implement the command specified
by the opcode and operand,
or doesnt implement the specified subunit */
or doesn’t implement the specified subunit */
#define AVRC_RSP_ACCEPT 9 /* The target executed or is executing the command */
#define AVRC_RSP_REJ 10 /* The target implements the command specified by the
opcode but cannot respond because the current state
of the target doesnt allow it */
of the target doesn’t allow it */
#define AVRC_RSP_IN_TRANS 11 /* The target implements the status command but it is
in a state of transition; the status command may
be retried at a future time */
@ -70,7 +70,7 @@
commands, the target returns stable and includes
the status results */
#define AVRC_RSP_CHANGED 13 /* The response frame contains a notification that the
target devices state has changed */
target device’s state has changed */
#define AVRC_RSP_INTERIM 15 /* For control commands, the target has accepted the
request but cannot return information within 100
milliseconds; for notify commands, the target accepted

View File

@ -3417,8 +3417,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class,
**
*******************************************************************************/
//extern
BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr);
BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport);
/*******************************************************************************
**

View File

@ -375,10 +375,7 @@ typedef UINT8 tBTM_BLE_AD_TYPE;
/* adv tx power level */
#define BTM_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */
#define BTM_BLE_ADV_TX_POWER_LOW 1 /* low tx power */
#define BTM_BLE_ADV_TX_POWER_MID 2 /* middle tx power */
#define BTM_BLE_ADV_TX_POWER_UPPER 3 /* upper tx power */
#define BTM_BLE_ADV_TX_POWER_MAX 4 /* maximum tx power */
#define BTM_BLE_ADV_TX_POWER_MAX 7 /* maximum tx power */
typedef UINT8 tBTM_BLE_ADV_TX_POWER;
/* adv tx power in dBm */
@ -582,6 +579,12 @@ typedef struct {
tBTM_BLE_REF_VALUE ref_value;
} tBTM_BLE_BATCH_SCAN_CB;
/// Ble scan duplicate type
enum {
BTM_BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */
BTM_BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */
BTM_BLE_SCAN_DUPLICATE_MAX = 0x2, /*!< 0x02 0xFF, Reserved for future use */
};
/* filter selection bit index */
#define BTM_BLE_PF_ADDR_FILTER 0
#define BTM_BLE_PF_SRVC_DATA 1
@ -1312,6 +1315,21 @@ void BTM_SecurityGrant(BD_ADDR bd_addr, UINT8 res);
//extern
void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
/*******************************************************************************
**
** Function BTM_BleSetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey);
/*******************************************************************************
**
** Function BTM_BleConfirmReply

View File

@ -64,7 +64,7 @@
#define GATT_NOT_ENCRYPTED 0x8e
#define GATT_CONGESTED 0x8f
#define GATT_DUP_REG 0x90
#define GATT_DUP_REG 0x90
#define GATT_ALREADY_OPEN 0x91
#define GATT_CANCEL 0x92
@ -111,6 +111,7 @@ typedef UINT8 tGATT_STATUS;
#define GATT_SIGN_CMD_WRITE 0xD2 /* changed in V4.0 1101-0010 (signed write) see write cmd above*/
#define GATT_OP_CODE_MAX GATT_HANDLE_VALUE_CONF + 1 /* 0x1E = 30 + 1 = 31*/
#define GATT_COMMAND_FLAG 0x40 /* Command Flag: set to one means commond */
#define GATT_HANDLE_IS_VALID(x) ((x) != 0)
@ -766,7 +767,7 @@ extern UINT16 GATTS_AddIncludeService (UINT16 service_handle,
**
*******************************************************************************/
extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
tGATT_PERM perm, tGATT_CHAR_PROP property,
tGATT_PERM perm, tGATT_CHAR_PROP property,
tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control);
/*******************************************************************************

View File

@ -401,6 +401,21 @@ extern void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res);
*******************************************************************************/
extern void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
/*******************************************************************************
**
** Function SMP_SetStaticPasskey
**
** Description This function is called to set static passkey
**
**
** Parameters: add - set static passkey when add is TRUE
** clear static passkey when add is FALSE
** passkey - static passkey
**
**
*******************************************************************************/
extern void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey);
/*******************************************************************************
**
** Function SMP_ConfirmReply

View File

@ -68,3 +68,26 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
* @return Returns true if the list contains the label, false otherwise.
*/
bool bootloader_common_label_search(const char *list, char *label);
/**
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
*
* This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
* For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
* The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
* For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
* For other partition types, the result is the SHA-256 of the entire partition.
*
* @param[in] address Address of partition.
* @param[in] size Size of partition.
* @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
* @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
*
* @return
* - ESP_OK: In case of successful operation.
* - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
* - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
* - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
* - ESP_FAIL: An allocation error occurred.
*/
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);

View File

@ -0,0 +1,49 @@
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stddef.h>
/**
* @brief Enable early entropy source for RNG
*
* Uses the SAR ADC to feed entropy into the HWRNG. The ADC is put
* into a test mode that reads the 1.1V internal reference source and
* feeds the LSB of data into the HWRNG.
*
* Can also be used from app code early during operation, if entropy
* is required before WiFi stack is initialised. Call this function
* from app code only if WiFi/BT are not yet enabled and I2S and SAR
* ADC are not in use.
*
* Call bootloader_random_disable() when done.
*/
void bootloader_random_enable(void);
/**
* @brief Disable early entropy source for RNG
*
* Disables SAR ADC source and resets the I2S hardware.
*
*/
void bootloader_random_disable(void);
/**
* @brief Fill buffer with 'length' random bytes
*
* @param buffer Pointer to buffer
* @param length This many bytes of random data will be copied to buffer
*/
void bootloader_fill_random(void *buffer, size_t length);

View File

@ -17,7 +17,9 @@
#include <stdbool.h>
#include "esp_attr.h"
#include "esp_err.h"
#ifndef BOOTLOADER_BUILD
#include "esp_spi_flash.h"
#endif
#include "soc/efuse_reg.h"
/**
@ -83,6 +85,8 @@ static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_e
* @note Take care not to power off the device while this function
* is running, or the partition currently being encrypted will be lost.
*
* @note RTC_WDT will reset while encryption operations will be performed (if RTC_WDT is configured).
*
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
* if a fatal error occured during encryption of all partitions.
*/
@ -91,6 +95,7 @@ esp_err_t esp_flash_encrypt_check_and_update(void);
/** @brief Encrypt-in-place a block of flash sectors
*
* @note This function resets RTC_WDT between operations with sectors.
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
*
@ -99,4 +104,14 @@ esp_err_t esp_flash_encrypt_check_and_update(void);
*/
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
/** @brief Write protect FLASH_CRYPT_CNT
*
* Intended to be called as a part of boot process if flash encryption
* is enabled but secure boot is not used. This should protect against
* serial re-flashing of an unauthorised code in absence of secure boot.
*
* @return
*/
void esp_flash_write_protect_crypt_cnt();
#endif

View File

@ -27,7 +27,7 @@
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature)
/* @brief Verify the partition table
*
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
* @param log_errors Log errors if the partition table is invalid.
@ -35,6 +35,13 @@
*
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
*/
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
/* This function is included for compatibility with the ESP-IDF v3.x API */
inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
}
#endif

View File

@ -36,7 +36,7 @@ typedef enum {
} esp_image_spi_mode_t;
/* SPI flash clock frequency */
enum {
typedef enum {
ESP_IMAGE_SPI_SPEED_40M,
ESP_IMAGE_SPI_SPEED_26M,
ESP_IMAGE_SPI_SPEED_20M,
@ -96,11 +96,12 @@ typedef struct {
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
uint32_t image_len; /* Length of image on flash, in bytes */
uint8_t image_digest[32]; /* appended SHA-256 digest */
} esp_image_metadata_t;
/* Mode selection for esp_image_load() */
typedef enum {
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errorsors. */
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */
@ -110,6 +111,11 @@ typedef enum {
/**
* @brief Verify and (optionally, in bootloader mode) load an app image.
*
* This name is deprecated and is included for compatibility with the ESP-IDF v3.x API.
* It will be removed in V4.0 version.
* Function has been renamed to esp_image_verify().
* Use function esp_image_verify() to verify a image. And use function bootloader_load_image() to load image from a bootloader space.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
@ -130,7 +136,60 @@ typedef enum {
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((deprecated));
/**
* @brief Verify an app image.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify and load an app image (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify the bootloader image.

View File

@ -17,6 +17,14 @@
#include <esp_err.h>
#include "soc/efuse_reg.h"
#include "sdkconfig.h"
#ifdef CONFIG_SECURE_BOOT_ENABLED
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
#error "internal sdkconfig error, secure boot should always enable all signature options"
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -25,83 +25,7 @@
extern "C" {
#endif
/**
* @brief Controller config options, depend on config mask.
* Config mask indicate which functions enabled, this means
* some options or parameters of some functions enabled by config mask.
*/
typedef struct {
uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint8_t scan_duplicate_mode; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
uint32_t controller_debug_flag; /*!< Controller debug log flag */
} esp_bt_controller_config_t;
#ifdef CONFIG_BT_ENABLED
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
#else
#define BT_HCI_UART_NO_DEFAULT 1
#endif /* BT_HCI_UART_NO_DEFAULT */
#ifdef CONFIG_BT_HCI_UART_BAUDRATE
#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
#else
#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
/* normal adv cache size */
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#else
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
#endif
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
#endif
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#else
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
#endif
#else
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
#endif
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
};
#else
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h");
#endif
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x5A5AA5A5
/**
* @brief Bluetooth mode for controller enable/disable
@ -113,6 +37,122 @@ typedef enum {
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
} esp_bt_mode_t;
#ifdef CONFIG_BT_ENABLED
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
#else
#define BT_HCI_UART_NO_DEFAULT 1
#endif /* BT_HCI_UART_NO_DEFAULT */
#ifdef CONFIG_BT_HCI_UART_BAUDRATE
#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
#else
#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
#ifdef CONFIG_SCAN_DUPLICATE_TYPE
#define SCAN_DUPLICATE_TYPE_VALUE CONFIG_SCAN_DUPLICATE_TYPE
#else
#define SCAN_DUPLICATE_TYPE_VALUE 0
#endif
/* normal adv cache size */
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#else
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
#endif
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
#endif
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#else
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
#endif
#else
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
#endif
#if defined(CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE
#elif defined(CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_CLASSIC_BT
#else
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BTDM
#endif
#define BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT 9 //Maximum BLE connection limitation
#define BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT 7 //Maximum ACL connection limitation
#define BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT 3 //Maximum SCO/eSCO connection limitation
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
.scan_duplicate_type = SCAN_DUPLICATE_TYPE_VALUE, \
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
.mode = BTDM_CONTROLLER_MODE_EFF, \
.ble_max_conn = CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF, \
.bt_max_acl_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF, \
.bt_max_sync_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF, \
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
};
#else
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h");
#endif
/**
* @brief Controller config options, depend on config mask.
* Config mask indicate which functions enabled, this means
* some options or parameters of some functions enabled by config mask.
*/
typedef struct {
/*
* Following parameters can be configured runtime, when call esp_bt_controller_init()
*/
uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
uint8_t scan_duplicate_mode; /*!< scan duplicate mode */
uint8_t scan_duplicate_type; /*!< scan duplicate type */
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
uint32_t controller_debug_flag; /*!< Controller debug log flag */
uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
uint8_t ble_max_conn; /*!< BLE maximum connection numbers */
uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */
/*
* Following parameters can not be configured runtime when call esp_bt_controller_init()
* It will be overwrite with a constant value which in menuconfig or from a macro.
* So, do not modify the value when esp_bt_controller_init()
*/
uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */
uint32_t magic; /*!< Magic number */
} esp_bt_controller_config_t;
/**
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
*/
@ -123,7 +163,6 @@ typedef enum {
ESP_BT_CONTROLLER_STATUS_NUM,
} esp_bt_controller_status_t;
/**
* @brief BLE tx power type
* ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed.
@ -202,7 +241,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
* BR/EDR power control will use the power in range of minimum value and maximum value.
* The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on.
* Please call the function after esp_bt_controller_enable and before any function which cause RF do TX.
* So you can call the function can before do discover, beofre profile init and so on.
* So you can call the function before doing discovery, profile init and so on.
* For example, if you want BR/EDR use the new TX power to do inquire, you should call
* this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING),
* please do inquire again after call this function.
@ -231,10 +270,11 @@ esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_l
esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path);
/**
* @brief Initialize BT controller to allocate task and other resource.
* @param cfg: Initial configuration of BT controller.
* This function should be called only once, before any other BT functions are called.
* @return ESP_OK - success, other - failed
* @brief Initialize BT controller to allocate task and other resource.
* This function should be called only once, before any other BT functions are called.
* @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some
* connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
@ -252,7 +292,8 @@ esp_err_t esp_bt_controller_deinit(void);
* Due to a known issue, you cannot call esp_bt_controller_enable() a second time
* to change the controller mode dynamically. To change controller mode, call
* esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.
* @param mode : the mode(BLE/BT/BTDM) to enable.
* @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be
* equal as the mode in "cfg" of esp_bt_controller_init().
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
@ -291,40 +332,70 @@ bool esp_vhci_host_check_send_available(void);
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
/** @brief esp_vhci_host_register_callback
* register the vhci referece callback, the call back
* register the vhci reference callback
* struct defined by vhci_host_callback structure.
* @param callback esp_vhci_host_callback type variable
* @return ESP_OK - success, ESP_FAIL - failed
*/
void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
/** @brief esp_bt_controller_mem_release
* release the memory by mode, if never use the bluetooth mode
* it can release the .bss, .data and other section to heap.
* The total size is about 70k bytes.
* release the controller memory as per the mode
*
* This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
*
* esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
* or after esp_bt_controller_deinit().
*
* Note that once BT controller memory is released, the process cannot be reversed. It means you can not use the bluetooth
* Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialisation time to free unused BT Classic memory.
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory.
*
* If user never use bluetooth controller, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)
* before esp_bt_controller_init or after esp_bt_controller_deinit.
*
* For example, user only use bluetooth to config SSID and PASSWORD of WIFI, after config, will never use bluetooth.
* Then, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) after esp_bt_controller_deinit.
* If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead,
* which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data
* consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of
* esp_bt_mem_release() function
*
* @param mode : the mode want to release memory
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
/** @brief esp_bt_mem_release
* release controller memory and BSS and data section of the BT/BLE host stack as per the mode
*
* This function first releases controller memory by internally calling esp_bt_controller_mem_release().
* Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap
*
* Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM)
* before esp_bt_controller_init or after esp_bt_controller_deinit.
*
* For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation".
* In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory.
* Below is the sequence of APIs to be called for such scenarios:
*
* esp_bluedroid_disable();
* esp_bluedroid_deinit();
* esp_bt_controller_disable();
* esp_bt_controller_deinit();
* esp_bt_mem_release(ESP_BT_MODE_BTDM);
*
* @param mode : the mode whose memory is to be released
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
/**
* @brief enable bluetooth to enter modem sleep
*
@ -377,10 +448,23 @@ bool esp_bt_controller_is_sleeping(void);
* Note that after this request, bluetooth controller may again enter sleep as long as the modem sleep is enabled
*
* Profiling shows that it takes several milliseconds to wakeup from modem sleep after this request.
* Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequncy of the former as the bluetooth low power clock source.
* Generally it takes longer if 32kHz XTAL is used than the main XTAL, due to the lower frequency of the former as the bluetooth low power clock source.
*/
void esp_bt_controller_wakeup_request(void);
/**
* @brief Manually clear scan duplicate list
*
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
* the amount of device in the filter can be configured in menuconfig.
*
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_scan_dupilcate_list_flush(void);
#ifdef __cplusplus
}
#endif

View File

@ -8,8 +8,10 @@
#define CONFIG_ESP32_PHY_MAX_TX_POWER 20
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16
#define CONFIG_MQTT_TRANSPORT_SSL 1
#define CONFIG_BLE_SMP_ENABLE 1
#define CONFIG_STACK_CHECK 1
#define CONFIG_MQTT_PROTOCOL_311 1
#define CONFIG_TCP_RECVMBOX_SIZE 6
#define CONFIG_LWIP_ETHARP_TRUST_IP_MAC 1
#define CONFIG_BLE_SCAN_DUPLICATE 1
@ -41,10 +43,13 @@
#define CONFIG_SPIFFS_CACHE 1
#define CONFIG_INT_WDT 1
#define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL 1
#define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN 3
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1 1
#define CONFIG_BT_STACK_NO_LOG 1
#define CONFIG_ESP_GRATUITOUS_ARP 1
#define CONFIG_MBEDTLS_ECDSA_C 1
#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1
#define CONFIG_HTTPD_MAX_REQ_HDR_LEN 512
#define CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE 0
#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1
#define CONFIG_MBEDTLS_ECDH_C 1
@ -54,7 +59,7 @@
#define CONFIG_MBEDTLS_SSL_ALPN 1
#define CONFIG_MBEDTLS_PEM_WRITE_C 1
#define CONFIG_BT_SPP_ENABLED 1
#define CONFIG_BT_RESERVE_DRAM 0x10000
#define CONFIG_BT_RESERVE_DRAM 0xdb5c
#define CONFIG_CXX_EXCEPTIONS 1
#define CONFIG_FATFS_FS_LOCK 0
#define CONFIG_IP_LOST_TIMER_INTERVAL 120
@ -71,6 +76,8 @@
#define CONFIG_TIMER_TASK_STACK_DEPTH 2048
#define CONFIG_TCP_MSS 1436
#define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1
#define CONFIG_BTDM_CONTROLLER_MODE_BTDM 1
#define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF 3
#define CONFIG_FATFS_CODEPAGE 850
#define CONFIG_ULP_COPROC_RESERVE_MEM 512
#define CONFIG_LWIP_MAX_UDP_PCBS 16
@ -102,6 +109,7 @@
#define CONFIG_TIMER_TASK_STACK_SIZE 4096
#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1
#define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1
#define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR 1
#define CONFIG_LWIP_DHCPS_LEASE_UNIT 60
#define CONFIG_SPIFFS_USE_MAGIC 1
#define CONFIG_TCPIP_TASK_STACK_SIZE 2560
@ -139,6 +147,7 @@
#define CONFIG_MDNS_MAX_SERVICES 10
#define CONFIG_ULP_COPROC_ENABLED 1
#define CONFIG_HFP_AUDIO_DATA_PATH_PCM 1
#define CONFIG_EMAC_CHECK_LINK_PERIOD_MS 2000
#define CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL 1
#define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1
#define CONFIG_LIBSODIUM_USE_MBEDTLS_SHA 1
@ -146,6 +155,7 @@
#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1
#define CONFIG_TCP_SYNMAXRTX 6
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0
#define CONFIG_HEAP_POISONING_LIGHT 1
#define CONFIG_PYTHON "python"
#define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1
@ -153,6 +163,7 @@
#define CONFIG_ESPTOOLPY_COMPRESSED 1
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
#define CONFIG_TCP_SND_BUF_DEFAULT 5744
#define CONFIG_GARP_TMR_INTERVAL 60
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
#define CONFIG_TCP_MSL 60000
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1
@ -161,8 +172,13 @@
#define CONFIG_ESP32_WIFI_RX_BA_WIN 6
#define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1
#define CONFIG_SPIFFS_USE_MTIME 1
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN 0
#define CONFIG_LWIP_DHCP_RESTORE_LAST_IP 1
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN 2
#define CONFIG_EMAC_TASK_STACK_SIZE 3072
#define CONFIG_SW_COEXIST_PREFERENCE_VALUE 2
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1
#define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1
#define CONFIG_PPP_SUPPORT 1
#define CONFIG_SPIRAM_SPEED_40M 1
#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 2048
@ -175,6 +191,7 @@
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32
#define CONFIG_HTTPD_MAX_URI_LEN 512
#define CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED 1
#define CONFIG_ARDUHAL_ESP_LOG 1
#define CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED 1
@ -204,6 +221,7 @@
#define CONFIG_WARN_WRITE_STRINGS 1
#define CONFIG_SPIFFS_OBJ_NAME_LEN 32
#define CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT 5
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF 2
#define CONFIG_LOG_BOOTLOADER_LEVEL_NONE 1
#define CONFIG_PARTITION_TABLE_MD5 1
#define CONFIG_TCPIP_RECVMBOX_SIZE 32
@ -218,6 +236,7 @@
#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1
#define CONFIG_WL_SECTOR_SIZE 4096
#define CONFIG_ESP32_DEBUG_OCDAWARE 1
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1
#define CONFIG_TIMER_TASK_PRIORITY 1
#define CONFIG_PPP_PAP_SUPPORT 1
#define CONFIG_MBEDTLS_TLS_CLIENT 1
@ -227,7 +246,10 @@
#define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1
#define CONFIG_MONITOR_BAUD 115200
#define CONFIG_ESP32_DEBUG_STUBS_ENABLE 1
#define CONFIG_TCPIP_LWIP 1
#define CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST 1
#define CONFIG_REDUCE_PHY_TX_POWER 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_FREERTOS_CORETIMER_0 1
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
#define CONFIG_MBEDTLS_HAVE_TIME 1
@ -239,25 +261,30 @@
#define CONFIG_MBEDTLS_TLS_SERVER 1
#define CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT 1
#define CONFIG_FREERTOS_ISR_STACKSIZE 1536
#define CONFIG_SUPPORT_TERMIOS 1
#define CONFIG_CLASSIC_BT_ENABLED 1
#define CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK 1
#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1
#define CONFIG_WL_SECTOR_SIZE_4096 1
#define CONFIG_OPTIMIZATION_LEVEL_DEBUG 1
#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1
#define CONFIG_SCAN_DUPLICATE_TYPE 0
#define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1
#define CONFIG_HFP_CLIENT_ENABLE 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA 1
#define CONFIG_SPI_SLAVE_ISR_IN_IRAM 1
#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32
#define CONFIG_BT_ACL_CONNECTIONS 4
#define CONFIG_FATFS_MAX_LFN 255
#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1
#define CONFIG_ESPTOOLPY_BAUD_921600B 1
#define CONFIG_BOOTLOADER_WDT_ENABLE 1
#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1
#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8
#define CONFIG_A2DP_ENABLE 1
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1
#define CONFIG_SPIFFS_PAGE_SIZE 256
#define CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED 1
#define CONFIG_PPP_MSCHAP_SUPPORT 1

View File

@ -0,0 +1,400 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _DRIVER_CAN_H_
#define _DRIVER_CAN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_types.h"
#include "esp_intr.h"
#include "esp_err.h"
#include "gpio.h"
/* -------------------- Default initializers and flags ---------------------- */
/** @cond */ //Doxy command to hide preprocessor definitions from docs
/**
* @brief Initializer macro for general configuration structure.
*
* This initializer macros allows the TX GPIO, RX GPIO, and operating mode to be
* configured. The other members of the general configuration structure are
* assigned default values.
*/
#define CAN_GENERAL_CONFIG_DEFAULT(tx_io_num, rx_io_num, op_mode) {.mode = op_mode, .tx_io = tx_io_num, .rx_io = rx_io_num, \
.clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, \
.tx_queue_len = 5, .rx_queue_len = 5, \
.alerts_enabled = CAN_ALERT_NONE, .clkout_divider = 0, }
/**
* @brief Initializer macros for timing configuration structure
*
* The following initializer macros offer commonly found bit rates.
*
* @note These timing values are based on the assumption APB clock is at 80MHz
*/
#define CAN_TIMING_CONFIG_25KBITS() {.brp = 128, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_50KBITS() {.brp = 80, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_100KBITS() {.brp = 40, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_125KBITS() {.brp = 32, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_250KBITS() {.brp = 16, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_500KBITS() {.brp = 8, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_800KBITS() {.brp = 4, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
#define CAN_TIMING_CONFIG_1MBITS() {.brp = 4, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
/**
* @brief Initializer macro for filter configuration to accept all IDs
*/
#define CAN_FILTER_CONFIG_ACCEPT_ALL() {.acceptance_code = 0, .acceptance_mask = 0xFFFFFFFF, .single_filter = true}
/**
* @brief Alert flags
*
* The following flags represents the various kind of alerts available in
* the CAN driver. These flags can be used when configuring/reconfiguring
* alerts, or when calling can_read_alerts().
*
* @note The CAN_ALERT_AND_LOG flag is not an actual alert, but will configure
* the CAN driver to log to UART when an enabled alert occurs.
*/
#define CAN_ALERT_TX_IDLE 0x0001 /**< Alert(1): No more messages to transmit */
#define CAN_ALERT_TX_SUCCESS 0x0002 /**< Alert(2): The previous transmission was successful */
#define CAN_ALERT_BELOW_ERR_WARN 0x0004 /**< Alert(4): Both error counters have dropped below error warning limit */
#define CAN_ALERT_ERR_ACTIVE 0x0008 /**< Alert(8): CAN controller has become error active */
#define CAN_ALERT_RECOVERY_IN_PROGRESS 0x0010 /**< Alert(16): CAN controller is undergoing bus recovery */
#define CAN_ALERT_BUS_RECOVERED 0x0020 /**< Alert(32): CAN controller has successfully completed bus recovery */
#define CAN_ALERT_ARB_LOST 0x0040 /**< Alert(64): The previous transmission lost arbitration */
#define CAN_ALERT_ABOVE_ERR_WARN 0x0080 /**< Alert(128): One of the error counters have exceeded the error warning limit */
#define CAN_ALERT_BUS_ERROR 0x0100 /**< Alert(256): A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus */
#define CAN_ALERT_TX_FAILED 0x0200 /**< Alert(512): The previous transmission has failed (for single shot transmission) */
#define CAN_ALERT_RX_QUEUE_FULL 0x0400 /**< Alert(1024): The RX queue is full causing a frame to be lost */
#define CAN_ALERT_ERR_PASS 0x0800 /**< Alert(2048): CAN controller has become error passive */
#define CAN_ALERT_BUS_OFF 0x1000 /**< Alert(4096): Bus-off condition occurred. CAN controller can no longer influence bus */
#define CAN_ALERT_ALL 0x1FFF /**< Bit mask to enable all alerts during configuration */
#define CAN_ALERT_NONE 0x0000 /**< Bit mask to disable all alerts during configuration */
#define CAN_ALERT_AND_LOG 0x2000 /**< Bit mask to enable alerts to also be logged when they occur */
/**
* @brief Message flags
*
* The message flags are used to indicate the type of message transmitted/received.
* Some flags also specify the type of transmission.
*/
#define CAN_MSG_FLAG_NONE 0x00 /**< No message flags (Standard Frame Format) */
#define CAN_MSG_FLAG_EXTD 0x01 /**< Extended Frame Format (29bit ID) */
#define CAN_MSG_FLAG_RTR 0x02 /**< Message is a Remote Transmit Request */
#define CAN_MSG_FLAG_SS 0x04 /**< Transmit as a Single Shot Transmission */
#define CAN_MSG_FLAG_SELF 0x08 /**< Transmit as a Self Reception Request */
#define CAN_MSG_FLAG_DLC_NON_COMP 0x10 /**< Message's Data length code is larger than 8. This will break compliance with CAN2.0B */
/**
* @brief Miscellaneous macros
*/
#define CAN_EXTD_ID_MASK 0x1FFFFFFF /**< Bit mask for 29 bit Extended Frame Format ID */
#define CAN_STD_ID_MASK 0x7FF /**< Bit mask for 11 bit Standard Frame Format ID */
#define CAN_MAX_DATA_LEN 8 /**< Maximum number of data bytes in a CAN2.0B frame */
#define CAN_IO_UNUSED (-1) /**< Marks GPIO as unused in CAN configuration */
/** @endcond */
/* ----------------------- Enum and Struct Definitions ---------------------- */
/**
* @brief CAN driver operating modes
*/
typedef enum {
CAN_MODE_NORMAL, /**< Normal operating mode where CAN controller can send/receive/acknowledge messages */
CAN_MODE_NO_ACK, /**< Transmission does not require acknowledgment. Use this mode for self testing */
CAN_MODE_LISTEN_ONLY, /**< The CAN controller will not influence the bus (No transmissions or acknowledgments) but can receive messages */
} can_mode_t;
/**
* @brief CAN driver states
*/
typedef enum {
CAN_STATE_STOPPED, /**< Stopped state. The CAN controller will not participate in any CAN bus activities */
CAN_STATE_RUNNING, /**< Running state. The CAN controller can transmit and receive messages */
CAN_STATE_BUS_OFF, /**< Bus-off state. The CAN controller cannot participate in bus activities until it has recovered */
CAN_STATE_RECOVERING, /**< Recovering state. The CAN controller is undergoing bus recovery */
} can_state_t;
/**
* @brief Structure for general configuration of the CAN driver
*
* @note Macro initializers are available for this structure
*/
typedef struct {
can_mode_t mode; /**< Mode of CAN controller */
gpio_num_t tx_io; /**< Transmit GPIO number */
gpio_num_t rx_io; /**< Receive GPIO number */
gpio_num_t clkout_io; /**< CLKOUT GPIO number (optional, set to -1 if unused) */
gpio_num_t bus_off_io; /**< Bus off indicator GPIO number (optional, set to -1 if unused) */
uint32_t tx_queue_len; /**< Number of messages TX queue can hold (set to 0 to disable TX Queue) */
uint32_t rx_queue_len; /**< Number of messages RX queue can hold */
uint32_t alerts_enabled; /**< Bit field of alerts to enable (see documentation) */
uint32_t clkout_divider; /**< CLKOUT divider. Can be 1 or any even number from 2 to 14 (optional, set to 0 if unused) */
} can_general_config_t;
/**
* @brief Structure for bit timing configuration of the CAN driver
*
* @note Macro initializers are available for this structure
*/
typedef struct {
uint8_t brp; /**< Baudrate prescaler (APB clock divider, even number from 2 to 128) */
uint8_t tseg_1; /**< Timing segment 1 (Number of time quanta, between 1 to 16) */
uint8_t tseg_2; /**< Timing segment 2 (Number of time quanta, 1 to 8) */
uint8_t sjw; /**< Synchronization Jump Width (Max time quanta jump for synchronize from 1 to 4) */
bool triple_sampling; /**< Enables triple sampling when the CAN controller samples a bit */
} can_timing_config_t;
/**
* @brief Structure for acceptance filter configuration of the CAN driver (see documentation)
*
* @note Macro initializers are available for this structure
*/
typedef struct {
uint32_t acceptance_code; /**< 32-bit acceptance code */
uint32_t acceptance_mask; /**< 32-bit acceptance mask */
bool single_filter; /**< Use Single Filter Mode (see documentation) */
} can_filter_config_t;
/**
* @brief Structure to store status information of CAN driver
*/
typedef struct {
can_state_t state; /**< Current state of CAN controller (Stopped/Running/Bus-Off/Recovery) */
uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */
uint32_t msgs_to_rx; /**< Number of messages in RX queue waiting to be read */
uint32_t tx_error_counter; /**< Current value of Transmit Error Counter */
uint32_t rx_error_counter; /**< Current value of Receive Error Counter */
uint32_t tx_failed_count; /**< Number of messages that failed transmissions */
uint32_t rx_missed_count; /**< Number of messages that were lost due to a full RX queue */
uint32_t arb_lost_count; /**< Number of instances arbitration was lost */
uint32_t bus_error_count; /**< Number of instances a bus error has occurred */
} can_status_info_t;
/**
* @brief Structure to store a CAN message
*
* @note The flags member is used to control the message type, and transmission
* type (see documentation for message flags)
*/
typedef struct {
uint32_t flags; /**< Bit field of message flags indicates frame/transmission type (see documentation) */
uint32_t identifier; /**< 11 or 29 bit identifier */
uint8_t data_length_code; /**< Data length code */
uint8_t data[CAN_MAX_DATA_LEN]; /**< Data bytes (not relevant in RTR frame) */
} can_message_t;
/* ----------------------------- Public API -------------------------------- */
/**
* @brief Install CAN driver
*
* This function installs the CAN driver using three configuration structures.
* The required memory is allocated and the CAN driver is placed in the stopped
* state after running this function.
*
* @param[in] g_config General configuration structure
* @param[in] t_config Timing configuration structure
* @param[in] f_config Filter configuration structure
*
* @note Macro initializers are available for the configuration structures (see documentation)
*
* @note To reinstall the CAN driver, call can_driver_uninstall() first
*
* @return
* - ESP_OK: Successfully installed CAN driver
* - ESP_ERR_INVALID_ARG: Arguments are invalid
* - ESP_ERR_NO_MEM: Insufficient memory
* - ESP_ERR_INVALID_STATE: Driver is already installed
*/
esp_err_t can_driver_install(const can_general_config_t *g_config, const can_timing_config_t *t_config, const can_filter_config_t *f_config);
/**
* @brief Uninstall the CAN driver
*
* This function uninstalls the CAN driver, freeing the memory utilized by the
* driver. This function can only be called when the driver is in the stopped
* state or the bus-off state.
*
* @warning The application must ensure that no tasks are blocked on TX/RX
* queues or alerts when this function is called.
*
* @return
* - ESP_OK: Successfully uninstalled CAN driver
* - ESP_ERR_INVALID_STATE: Driver is not in stopped/bus-off state, or is not installed
*/
esp_err_t can_driver_uninstall();
/**
* @brief Start the CAN driver
*
* This function starts the CAN driver, putting the CAN driver into the running
* state. This allows the CAN driver to participate in CAN bus activities such
* as transmitting/receiving messages. The RX queue is reset in this function,
* clearing any unread messages. This function can only be called when the CAN
* driver is in the stopped state.
*
* @return
* - ESP_OK: CAN driver is now running
* - ESP_ERR_INVALID_STATE: Driver is not in stopped state, or is not installed
*/
esp_err_t can_start();
/**
* @brief Stop the CAN driver
*
* This function stops the CAN driver, preventing any further message from being
* transmitted or received until can_start() is called. Any messages in the TX
* queue are cleared. Any messages in the RX queue should be read by the
* application after this function is called. This function can only be called
* when the CAN driver is in the running state.
*
* @warning A message currently being transmitted/received on the CAN bus will
* be ceased immediately. This may lead to other CAN nodes interpreting
* the unfinished message as an error.
*
* @return
* - ESP_OK: CAN driver is now Stopped
* - ESP_ERR_INVALID_STATE: Driver is not in running state, or is not installed
*/
esp_err_t can_stop();
/**
* @brief Transmit a CAN message
*
* This function queues a CAN message for transmission. Transmission will start
* immediately if no other messages are queued for transmission. If the TX queue
* is full, this function will block until more space becomes available or until
* it timesout. If the TX queue is disabled (TX queue length = 0 in configuration),
* this function will return immediately if another message is undergoing
* transmission. This function can only be called when the CAN driver is in the
* running state and cannot be called under Listen Only Mode.
*
* @param[in] message Message to transmit
* @param[in] ticks_to_wait Number of FreeRTOS ticks to block on the TX queue
*
* @note This function does not guarantee that the transmission is successful.
* The TX_SUCCESS/TX_FAILED alert can be enabled to alert the application
* upon the success/failure of a transmission.
*
* @note The TX_IDLE alert can be used to alert the application when no other
* messages are awaiting transmission.
*
* @return
* - ESP_OK: Transmission successfully queued/initiated
* - ESP_ERR_INVALID_ARG: Arguments are invalid
* - ESP_ERR_TIMEOUT: Timed out waiting for space on TX queue
* - ESP_FAIL: TX queue is disabled and another message is currently transmitting
* - ESP_ERR_INVALID_STATE: CAN driver is not in running state, or is not installed
* - ESP_ERR_NOT_SUPPORTED: Listen Only Mode does not support transmissions
*/
esp_err_t can_transmit(const can_message_t *message, TickType_t ticks_to_wait);
/**
* @brief Receive a CAN message
*
* This function receives a message from the RX queue. The flags field of the
* message structure will indicate the type of message received. This function
* will block if there are no messages in the RX queue
*
* @param[out] message Received message
* @param[in] ticks_to_wait Number of FreeRTOS ticks to block on RX queue
*
* @warning The flags field of the received message should be checked to determine
* if the received message contains any data bytes.
*
* @return
* - ESP_OK: Message successfully received from RX queue
* - ESP_ERR_TIMEOUT: Timed out waiting for message
* - ESP_ERR_INVALID_ARG: Arguments are invalid
* - ESP_ERR_INVALID_STATE: CAN driver is not installed
*/
esp_err_t can_receive(can_message_t *message, TickType_t ticks_to_wait);
/**
* @brief Read CAN driver alerts
*
* This function will read the alerts raised by the CAN driver. If no alert has
* been when this function is called, this function will block until an alert
* occurs or until it timeouts.
*
* @param[out] alerts Bit field of raised alerts (see documentation for alert flags)
* @param[in] ticks_to_wait Number of FreeRTOS ticks to block for alert
*
* @note Multiple alerts can be raised simultaneously. The application should
* check for all alerts that have been enabled.
*
* @return
* - ESP_OK: Alerts read
* - ESP_ERR_TIMEOUT: Timed out waiting for alerts
* - ESP_ERR_INVALID_ARG: Arguments are invalid
* - ESP_ERR_INVALID_STATE: CAN driver is not installed
*/
esp_err_t can_read_alerts(uint32_t *alerts, TickType_t ticks_to_wait);
/**
* @brief Reconfigure which alerts are enabled
*
* This function reconfigures which alerts are enabled. If there are alerts
* which have not been read whilst reconfiguring, this function can read those
* alerts.
*
* @param[in] alerts_enabled Bit field of alerts to enable (see documentation for alert flags)
* @param[out] current_alerts Bit field of currently raised alerts. Set to NULL if unused
*
* @return
* - ESP_OK: Alerts reconfigured
* - ESP_ERR_INVALID_STATE: CAN driver is not installed
*/
esp_err_t can_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_alerts);
/**
* @brief Start the bus recovery process
*
* This function initiates the bus recovery process when the CAN driver is in
* the bus-off state. Once initiated, the CAN driver will enter the recovering
* state and wait for 128 occurrences of the bus-free signal on the CAN bus
* before returning to the stopped state. This function will reset the TX queue,
* clearing any messages pending transmission.
*
* @note The BUS_RECOVERED alert can be enabled to alert the application when
* the bus recovery process completes.
*
* @return
* - ESP_OK: Bus recovery started
* - ESP_ERR_INVALID_STATE: CAN driver is not in the bus-off state, or is not installed
*/
esp_err_t can_initiate_recovery();
/**
* @brief Get current status information of the CAN driver
*
* @param[out] status_info Status information
*
* @return
* - ESP_OK: Status information retrieved
* - ESP_ERR_INVALID_ARG: Arguments are invalid
* - ESP_ERR_INVALID_STATE: CAN driver is not installed
*/
esp_err_t can_get_status_info(can_status_info_t *status_info);
#ifdef __cplusplus
}
#endif
#endif /*_DRIVER_CAN_H_*/

View File

@ -249,13 +249,13 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);
/**
* @brief Reset an gpio to default state (select gpio function, enable pullup and disable input and output).
*
*
* @param gpio_num GPIO number.
*
*
* @note This function also configures the IOMUX for this pin to the GPIO
* function, and disconnects any other peripheral output configured via GPIO
* Matrix.
*
*
* @return Always return ESP_OK.
*/
esp_err_t gpio_reset_pin(gpio_num_t gpio_num);
@ -359,27 +359,27 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
/**
* @brief Enable GPIO wake-up function.
*
* @param gpio_num GPIO number.
*
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
* @brief Enable GPIO wake-up function.
*
* @param gpio_num GPIO number.
*
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
* @brief Disable GPIO wake-up function.
*
* @param gpio_num GPIO number
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
* @brief Disable GPIO wake-up function.
*
* @param gpio_num GPIO number
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
/**

File diff suppressed because it is too large Load Diff

View File

@ -455,7 +455,7 @@ void ledc_fade_func_uninstall();
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode);
/**
* @brief A thread-safe API to set duty for LEDC channel and update the settings immediately
* @brief A thread-safe API to set duty for LEDC channel and return when duty updated.
* @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped.
* Other duty operations will have to wait until the fade operation has finished.
*

File diff suppressed because it is too large Load Diff

View File

@ -98,6 +98,8 @@ typedef intr_handle_t pcnt_isr_handle_t;
/**
* @brief Configure Pulse Counter unit
* @note
* This function will disable three events: PCNT_EVT_L_LIM, PCNT_EVT_H_LIM, PCNT_EVT_ZERO.
*
* @param pcnt_config Pointer of Pulse Counter unit configure parameter
*
@ -233,16 +235,19 @@ esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16
/**
* @brief Register PCNT interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
* Please do not use pcnt_isr_service_install if this function was called.
*
* @param fn Interrupt handler function.
* @param arg Parameter for handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
* be returned here. Calling esp_intr_free to unregister this ISR service if needed,
* but only if the handle is not NULL.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags.
* - ESP_ERR_INVALID_ARG Function pointer error.
*/
esp_err_t pcnt_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, pcnt_isr_handle_t *handle);
@ -358,7 +363,8 @@ esp_err_t pcnt_isr_handler_add(pcnt_unit_t unit, void(*isr_handler)(void *), voi
/**
* @brief Install PCNT ISR service.
* @note We can manage different interrupt service for each unit.
* Please do not use pcnt_isr_register if this function was called.
* This function will use the default ISR handle service, Calling pcnt_isr_service_uninstall to
* uninstall the default service if needed. Please do not use pcnt_isr_register if this function was called.
*
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.

View File

@ -35,7 +35,7 @@ typedef enum {
* @brief Determine if the specified GPIO is a valid RTC GPIO.
*
* @param gpio_num GPIO number
* @return true if GPIO is valid for RTC GPIO use. talse otherwise.
* @return true if GPIO is valid for RTC GPIO use. false otherwise.
*/
inline static bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
{
@ -223,29 +223,52 @@ esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num);
void rtc_gpio_force_hold_dis_all();
/**
* @brief Set RTC GPIO pad drive capability
*
* @param gpio_num GPIO number, only support output GPIOs
* @param strength Drive capability of the pad
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
* @brief Set RTC GPIO pad drive capability
*
* @param gpio_num GPIO number, only support output GPIOs
* @param strength Drive capability of the pad
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength);
/**
* @brief Get RTC GPIO pad drive capability
*
* @param gpio_num GPIO number, only support output GPIOs
* @param strength Pointer to accept drive capability of the pad
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
* @brief Get RTC GPIO pad drive capability
*
* @param gpio_num GPIO number, only support output GPIOs
* @param strength Pointer to accept drive capability of the pad
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* strength);
/**
* @brief Enable wakeup from sleep mode using specific GPIO
* @param gpio_num GPIO number
* @param intr_type Wakeup on high level (GPIO_INTR_HIGH_LEVEL) or low level
* (GPIO_INTR_LOW_LEVEL)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO, or intr_type is not
* one of GPIO_INTR_HIGH_LEVEL, GPIO_INTR_LOW_LEVEL.
*/
esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
* @brief Disable wakeup from sleep mode using specific GPIO
* @param gpio_num GPIO number
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO
*/
esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num);
#ifdef __cplusplus
}
#endif

View File

@ -47,10 +47,12 @@ typedef enum {
/// Timing of SDIO slave
typedef enum {
SDIO_SLAVE_TIMING_NSEND_PSAMPLE = 0,///< Send at negedge, and sample at posedge. Default value for SD protocol.
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
SDIO_SLAVE_TIMING_PSEND_PSAMPLE, ///< Send at posedge, and sample at posedge
SDIO_SLAVE_TIMING_PSEND_PSAMPLE = 0,/**< Send at posedge, and sample at posedge. Default value for HS mode.
* Normally there's no problem using this to work in DS mode.
*/
SDIO_SLAVE_TIMING_NSEND_PSAMPLE ,///< Send at negedge, and sample at posedge. Default value for DS mode and below.
SDIO_SLAVE_TIMING_PSEND_NSAMPLE, ///< Send at posedge, and sample at negedge
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
} sdio_slave_timing_t;
/// Configuration of SDIO slave mode
@ -72,20 +74,20 @@ typedef struct {
///< Buffer size of the slave pre-defined between host and slave before communication. All receive buffer given to the driver should be larger than this.
sdio_event_cb_t event_cb; ///< when the host interrupts slave, this callback will be called with interrupt number (0-7).
uint32_t flags; ///< Features to be enabled for the slave, combinations of ``SDIO_SLAVE_FLAG_*``.
#define SDIO_SLAVE_FLAG_DAT2_DISABLED BIT(0) /**< It is required by the SD specification that all 4 data
lines should be used and pulled up even in 1-bit mode or SPI mode. However, as a feature, the user can speicfy
this flag to make use of DAT2 pin in 1-bit mode. Note that the host cannot read CCCR registers to know we don't
#define SDIO_SLAVE_FLAG_DAT2_DISABLED BIT(0) /**< It is required by the SD specification that all 4 data
lines should be used and pulled up even in 1-bit mode or SPI mode. However, as a feature, the user can specify
this flag to make use of DAT2 pin in 1-bit mode. Note that the host cannot read CCCR registers to know we don't
support 4-bit mode anymore, please do this at your own risk.
*/
#define SDIO_SLAVE_FLAG_HOST_INTR_DISABLED BIT(1) /**< The DAT1 line is used as the interrupt line in SDIO
protocol. However, as a feature, the user can speicfy this flag to make use of DAT1 pin of the slave in 1-bit
#define SDIO_SLAVE_FLAG_HOST_INTR_DISABLED BIT(1) /**< The DAT1 line is used as the interrupt line in SDIO
protocol. However, as a feature, the user can specify this flag to make use of DAT1 pin of the slave in 1-bit
mode. Note that the host has to do polling to the interrupt registers to know whether there are interrupts from
the slave. And it cannot read CCCR registers to know we don't support 4-bit mode anymore, please do this at
the slave. And it cannot read CCCR registers to know we don't support 4-bit mode anymore, please do this at
your own risk.
*/
#define SDIO_SLAVE_FLAG_INTERNAL_PULLUP BIT(2) /**< Enable internal pullups for enabled pins. It is required
by the SD specification that all the 4 data lines should be pulled up even in 1-bit mode or SPI mode. Note that
the internal pull-ups are not sufficient for stable communication, please do connect external pull-ups on the
#define SDIO_SLAVE_FLAG_INTERNAL_PULLUP BIT(2) /**< Enable internal pullups for enabled pins. It is required
by the SD specification that all the 4 data lines should be pulled up even in 1-bit mode or SPI mode. Note that
the internal pull-ups are not sufficient for stable communication, please do connect external pull-ups on the
bus. This is only for example and debug use.
*/
} sdio_slave_config_t;
@ -214,12 +216,12 @@ uint8_t* sdio_slave_recv_get_buf(sdio_slave_buf_handle_t handle, size_t *len_o);
esp_err_t sdio_slave_send_queue(uint8_t* addr, size_t len, void* arg, TickType_t wait);
/** Return the ownership of a finished transaction.
* @param arg_o Argument of the finished transaction.
* @param out_arg Argument of the finished transaction. Set to NULL if unused.
* @param wait Time to wait if there's no finished sending transaction.
*
* @return ESP_ERR_TIMEOUT if no transaction finished, or ESP_OK if succeed.
*/
esp_err_t sdio_slave_send_get_finished(void** arg_o, TickType_t wait);
esp_err_t sdio_slave_send_get_finished(void** out_arg, TickType_t wait);
/** Start a new sending transfer, and wait for it (blocked) to be finished.
*

View File

@ -31,11 +31,13 @@
#define MMC_SEND_EXT_CSD 8 /* R1 */
#define MMC_SEND_CSD 9 /* R2 */
#define MMC_SEND_CID 10 /* R1 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* R1 */
#define MMC_STOP_TRANSMISSION 12 /* R1B */
#define MMC_SEND_STATUS 13 /* R1 */
#define MMC_SET_BLOCKLEN 16 /* R1 */
#define MMC_READ_BLOCK_SINGLE 17 /* R1 */
#define MMC_READ_BLOCK_MULTIPLE 18 /* R1 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* R1 */
#define MMC_SET_BLOCK_COUNT 23 /* R1 */
#define MMC_WRITE_BLOCK_SINGLE 24 /* R1 */
#define MMC_WRITE_BLOCK_MULTIPLE 25 /* R1 */
@ -89,6 +91,7 @@
/* SD mode R1 response type bits */
#define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer */
#define MMC_R1_APP_CMD (1<<5) /* app. commands supported */
#define MMC_R1_SWITCH_ERROR (1<<7) /* switch command did not succeed */
/* SPI mode R1 response type bits */
#define SD_SPI_R1_IDLE_STATE (1<<0)
@ -129,6 +132,13 @@
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_SEC_COUNT 212 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_CMD_SET 191 /* R/W */
#define EXT_CSD_S_CMD_SET 504 /* RO */
/* EXT_CSD field definitions */
#define EXT_CSD_CMD_SET_NORMAL (1U << 0)
@ -151,16 +161,19 @@
/* EXT_CSD_CARD_TYPE */
/* The only currently valid values for this field are 0x01, 0x03, 0x07,
* 0x0B and 0x0F. */
#define EXT_CSD_CARD_TYPE_F_26M (1 << 0)
#define EXT_CSD_CARD_TYPE_F_52M (1 << 1)
#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2)
#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3)
#define EXT_CSD_CARD_TYPE_F_26M (1 << 0) /* SDR at "rated voltages */
#define EXT_CSD_CARD_TYPE_F_52M (1 << 1) /* SDR at "rated voltages */
#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2) /* DDR, 1.8V or 3.3V I/O */
#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3) /* DDR, 1.2V I/O */
#define EXT_CSD_CARD_TYPE_26M 0x01
#define EXT_CSD_CARD_TYPE_52M 0x03
#define EXT_CSD_CARD_TYPE_52M_V18 0x07
#define EXT_CSD_CARD_TYPE_52M_V12 0x0b
#define EXT_CSD_CARD_TYPE_52M_V12_18 0x0f
/* EXT_CSD MMC */
#define EXT_CSD_MMC_SIZE 512
/* MMC_SWITCH access mode */
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in value */
@ -445,5 +458,9 @@ static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len)
/* CISTPL_FUNCID codes */
#define TPLFID_FUNCTION_SDIO 0x0c
/* Timing */
#define SDMMC_TIMING_LEGACY 0
#define SDMMC_TIMING_HIGHSPEED 1
#define SDMMC_TIMING_MMC_DDR52 2
#endif //_SDMMC_DEFS_H_

View File

@ -33,13 +33,17 @@ extern "C" {
* Uses SDMMC peripheral, with 4-bit mode enabled, and max frequency set to 20MHz
*/
#define SDMMC_HOST_DEFAULT() {\
.flags = SDMMC_HOST_FLAG_4BIT, \
.flags = SDMMC_HOST_FLAG_8BIT | \
SDMMC_HOST_FLAG_4BIT | \
SDMMC_HOST_FLAG_1BIT | \
SDMMC_HOST_FLAG_DDR, \
.slot = SDMMC_HOST_SLOT_1, \
.max_freq_khz = SDMMC_FREQ_DEFAULT, \
.io_voltage = 3.3f, \
.init = &sdmmc_host_init, \
.set_bus_width = &sdmmc_host_set_bus_width, \
.get_bus_width = &sdmmc_host_get_slot_width, \
.set_bus_ddr_mode = &sdmmc_host_set_bus_ddr_mode, \
.set_card_clk = &sdmmc_host_set_card_clk, \
.do_transaction = &sdmmc_host_do_transaction, \
.deinit = &sdmmc_host_deinit, \
@ -150,6 +154,16 @@ size_t sdmmc_host_get_slot_width(int slot);
*/
esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz);
/**
* @brief Enable or disable DDR mode of SD interface
* @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param ddr_enabled enable or disable DDR mode
* @return
* - ESP_OK on success
* - ESP_ERR_NOT_SUPPORTED if DDR mode is not supported on this slot
*/
esp_err_t sdmmc_host_set_bus_ddr_mode(int slot, bool ddr_enabled);
/**
* @brief Send command to the card and get response
*

View File

@ -56,6 +56,13 @@ typedef struct {
int bus_width; /*!< bus widths supported by card: BIT(0) — 1-bit bus, BIT(2) — 4-bit bus */
} sdmmc_scr_t;
/**
* Decoded values of Extended Card Specific Data
*/
typedef struct {
uint8_t power_class; /*!< Power class used by the card */
} sdmmc_ext_csd_t;
/**
* SD/MMC command response buffer
*/
@ -103,6 +110,8 @@ typedef struct {
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
/* special flags */
#define SCF_WAIT_BUSY 0x2000 /*!< Wait for completion of card busy signal before returning */
/** @endcond */
esp_err_t error; /*!< error returned from transfer */
int timeout_ms; /*!< response timeout, in milliseconds */
@ -120,15 +129,19 @@ typedef struct {
#define SDMMC_HOST_FLAG_4BIT BIT(1) /*!< host supports 4-line SD and MMC protocol */
#define SDMMC_HOST_FLAG_8BIT BIT(2) /*!< host supports 8-line MMC protocol */
#define SDMMC_HOST_FLAG_SPI BIT(3) /*!< host supports SPI protocol */
#define SDMMC_HOST_FLAG_DDR BIT(4) /*!< host supports DDR mode for SD/MMC */
int slot; /*!< slot number, to be passed to host functions */
int max_freq_khz; /*!< max frequency supported by the host */
#define SDMMC_FREQ_DEFAULT 20000 /*!< SD/MMC Default speed (limited by clock divider) */
#define SDMMC_FREQ_HIGHSPEED 40000 /*!< SD High speed (limited by clock divider) */
#define SDMMC_FREQ_PROBING 400 /*!< SD/MMC probing speed */
#define SDMMC_FREQ_52M 52000 /*!< MMC 52MHz speed */
#define SDMMC_FREQ_26M 26000 /*!< MMC 26MHz speed */
float io_voltage; /*!< I/O voltage used by the controller (voltage switching is not supported) */
esp_err_t (*init)(void); /*!< Host function to initialize the driver */
esp_err_t (*set_bus_width)(int slot, size_t width); /*!< host function to set bus width */
size_t (*get_bus_width)(int slot); /*!< host function to get bus width */
esp_err_t (*set_bus_ddr_mode)(int slot, bool ddr_enable); /*!< host function to set DDR mode */
esp_err_t (*set_card_clk)(int slot, uint32_t freq_khz); /*!< host function to set card clock frequency */
esp_err_t (*do_transaction)(int slot, sdmmc_command_t* cmdinfo); /*!< host function to do a transaction */
esp_err_t (*deinit)(void); /*!< host function to deinitialize the driver */
@ -146,11 +159,16 @@ typedef struct {
sdmmc_cid_t cid; /*!< decoded CID (Card IDentification) register value */
sdmmc_csd_t csd; /*!< decoded CSD (Card-Specific Data) register value */
sdmmc_scr_t scr; /*!< decoded SCR (SD card Configuration Register) value */
sdmmc_ext_csd_t ext_csd; /*!< decoded EXT_CSD (Extended Card Specific Data) register value */
uint16_t rca; /*!< RCA (Relative Card Address) */
uint16_t max_freq_khz; /*!< Maximum frequency, in kHz, supported by the card */
uint32_t is_mem : 1; /*!< Bit indicates if the card is a memory card */
uint32_t is_sdio : 1; /*!< Bit indicates if the card is an IO card */
uint32_t is_mmc : 1; /*!< Bit indicates if the card is MMC */
uint32_t num_io_functions : 3; /*!< If is_sdio is 1, contains the number of IO functions on the card */
uint32_t reserved : 27; /*!< Reserved for future expansion */
uint32_t log_bus_width : 2; /*!< log2(bus width supported by card) */
uint32_t is_ddr : 1; /*!< Card supports DDR mode */
uint32_t reserved : 23; /*!< Reserved for future expansion */
} sdmmc_card_t;

View File

@ -41,6 +41,7 @@ extern "C" {
.init = &sdspi_host_init, \
.set_bus_width = NULL, \
.get_bus_width = NULL, \
.set_bus_ddr_mode = NULL, \
.set_card_clk = &sdspi_host_set_card_clk, \
.do_transaction = &sdspi_host_do_transaction, \
.deinit = &sdspi_host_deinit, \

View File

@ -21,6 +21,7 @@
#include "esp_err.h"
#include "rom/lldesc.h"
#include "soc/spi_periph.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C"
@ -31,6 +32,34 @@ extern "C"
//Maximum amount of bytes that can be put in one DMA descriptor
#define SPI_MAX_DMA_LEN (4096-4)
/**
* Transform unsigned integer of length <= 32 bits to the format which can be
* sent by the SPI driver directly.
*
* E.g. to send 9 bits of data, you can:
*
* uint16_t data = SPI_SWAP_DATA_TX(0x145, 9);
*
* Then points tx_buffer to ``&data``.
*
* @param data Data to be sent, can be uint8_t, uint16_t or uint32_t. @param
* len Length of data to be sent, since the SPI peripheral sends from the MSB,
* this helps to shift the data to the MSB.
*/
#define SPI_SWAP_DATA_TX(data, len) __builtin_bswap32((uint32_t)data<<(32-len))
/**
* Transform received data of length <= 32 bits to the format of an unsigned integer.
*
* E.g. to transform the data of 15 bits placed in a 4-byte array to integer:
*
* uint16_t data = SPI_SWAP_DATA_RX(*(uint32_t*)t->rx_data, 15);
*
* @param data Data to be rearranged, can be uint8_t, uint16_t or uint32_t.
* @param len Length of data received, since the SPI peripheral writes from
* the MSB, this helps to shift the data to the LSB.
*/
#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
/**
* @brief Enum with the three SPI peripherals that are software-accessible in it
@ -45,7 +74,7 @@ typedef enum {
* @brief This is a configuration structure for a SPI bus.
*
* You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the
* GPIO matrix to route the signals. An exception is made when all signals either can be routed through
* GPIO matrix to route the signals. An exception is made when all signals either can be routed through
* the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds.
*
* @note Be advised that the slave driver does not use the quadwp/quadhd lines and fields in spi_bus_config_t refering to these lines will be ignored and can thus safely be left uninitialized.
@ -81,20 +110,20 @@ bool spicommon_periph_free(spi_host_device_t host);
/**
* @brief Try to claim a SPI DMA channel
*
*
* Call this if your driver wants to use SPI with a DMA channnel.
*
*
* @param dma_chan channel to claim
*
*
* @return True if success; false otherwise.
*/
bool spicommon_dma_chan_claim(int dma_chan);
/**
* @brief Return the SPI DMA channel so other driver can claim it, or just to power down DMA.
*
*
* @param dma_chan channel to return
*
*
* @return True if success; false otherwise.
*/
bool spicommon_dma_chan_free(int dma_chan);
@ -113,7 +142,7 @@ bool spicommon_dma_chan_free(int dma_chan);
* @brief Connect a SPI peripheral to GPIO pins
*
* This routine is used to connect a SPI peripheral to the IO-pads and DMA channel given in
* the arguments. Depending on the IO-pads requested, the routing is done either using the
* the arguments. Depending on the IO-pads requested, the routing is done either using the
* IO_mux or using the GPIO matrix.
*
* @param host SPI peripheral to be routed
@ -123,7 +152,7 @@ bool spicommon_dma_chan_free(int dma_chan);
* - ``SPICOMMON_BUSFLAG_MASTER``: Initialize I/O in master mode
* - ``SPICOMMON_BUSFLAG_SLAVE``: Initialize I/O in slave mode
* - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: Pins set should match the iomux pins of the controller.
* - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
* - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
* Make sure SCLK/MISO/MOSI is/are set to a valid GPIO. Also check output capability according to the mode.
* - ``SPICOMMON_BUSFLAG_DUAL``: Make sure both MISO and MOSI are output capable so that DIO mode is capable.
* - ``SPICOMMON_BUSFLAG_WPHD`` Make sure WP and HD are set to valid output GPIOs.
@ -136,7 +165,7 @@ bool spicommon_dma_chan_free(int dma_chan);
* - ``SPICOMMON_BUSFLAG_DUAL``: The bus is capable with DIO mode.
* - ``SPICOMMON_BUSFLAG_WPHD`` The bus has WP and HD connected.
* - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
* @return
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
@ -145,10 +174,10 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
/**
* @brief Free the IO used by a SPI peripheral
* @deprecated Use spicommon_bus_free_io_cfg instead.
*
*
* @param host SPI peripheral to be freed
*
* @return
*
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
@ -158,8 +187,8 @@ esp_err_t spicommon_bus_free_io(spi_host_device_t host) __attribute__((deprecate
* @brief Free the IO used by a SPI peripheral
*
* @param bus_cfg Bus config struct which defines which pins to be used.
*
* @return
*
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
@ -240,10 +269,10 @@ typedef void(*dmaworkaround_cb_t)(void *arg);
* @note In some (well-defined) cases in the ESP32 (at least rev v.0 and v.1), a SPI DMA channel will get confused. This can be remedied
* by resetting the SPI DMA hardware in case this happens. Unfortunately, the reset knob used for thsi will reset _both_ DMA channels, and
* as such can only done safely when both DMA channels are idle. These functions coordinate this.
*
*
* Essentially, when a reset is needed, a driver can request this using spicommon_dmaworkaround_req_reset. This is supposed to be called
* with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
* If the other DMA channel is still busy, it will return false; as soon as the other DMA channel is done, however, it will reset the
* with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
* If the other DMA channel is still busy, it will return false; as soon as the other DMA channel is done, however, it will reset the
* DMA subsystem and call the callback. The callback is then supposed to be used to continue the SPI drivers activity.
*
* @param dmachan DMA channel associated with the SPI host that needs a reset

View File

@ -122,6 +122,7 @@ esp_err_t touch_pad_init();
/**
* @brief Un-install touch pad driver.
* @note After this function is called, other touch functions are prohibited from being called.
* @return
* - ESP_OK Success
* - ESP_FAIL Touch pad driver not initialized
@ -550,6 +551,15 @@ esp_err_t touch_pad_filter_stop();
*/
esp_err_t touch_pad_filter_delete();
/**
* @brief Get the touch pad which caused wakeup from sleep
* @param pad_num pointer to touch pad which caused wakeup
* @return
* - ESP_OK Success
* - ESP_FAIL get status err
*/
esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num);
#ifdef __cplusplus
}
#endif

View File

@ -46,6 +46,17 @@ extern "C" {
#define UART_INVERSE_TXD (UART_TXD_INV_M) /*!< UART TXD output inverse*/
#define UART_INVERSE_RTS (UART_RTS_INV_M) /*!< UART RTS output inverse*/
/**
* @brief UART mode selection
*/
typedef enum {
UART_MODE_UART = 0x00, /*!< mode: regular UART mode*/
UART_MODE_RS485_HALF_DUPLEX = 0x01, /*!< mode: half duplex RS485 UART mode control by RTS pin */
UART_MODE_IRDA = 0x02, /*!< mode: IRDA UART mode*/
UART_MODE_RS485_COLLISION_DETECT = 0x03, /*!< mode: RS485 collision detection UART mode (used for test purposes)*/
UART_MODE_RS485_APP_CTRL = 0x04, /*!< mode: application control RS485 UART mode (used for test purposes)*/
} uart_mode_t;
/**
* @brief UART word length constants
*/
@ -54,7 +65,7 @@ typedef enum {
UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/
UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/
UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/
UART_DATA_BITS_MAX = 0X4,
UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;
/**
@ -249,8 +260,8 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate);
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param inverse_mask Choose the wires that need to be inverted.
* Inverse_mask should be chosen from
UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
combined with OR operation.
* UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
* combined with OR operation.
*
* @return
* - ESP_OK Success
@ -474,7 +485,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level);
esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint16_t idle_num);
/**
* @brief Set UART configuration parameters.
* @brief Set UART configuration parameters.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_config UART parameter settings
@ -486,7 +497,7 @@ esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint16_t idle_num);
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config);
/**
* @brief Configure UART interrupts.
* @brief Configure UART interrupts.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param intr_conf UART interrupt settings
@ -552,8 +563,8 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
* @note This function should only be used when UART TX buffer is not enabled.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param buffer data buffer address
* @param len data length to send
* @param buffer data buffer address
* @param len data length to send
*
* @return
* - (-1) Parameter error
@ -571,8 +582,8 @@ int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param src data buffer address
* @param size data length to send
* @param src data buffer address
* @param size data length to send
*
* @return
* - (-1) Parameter error
@ -581,7 +592,7 @@ int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);
int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size);
/**
* @brief Send data to the UART port from a given buffer and length.
* @brief Send data to the UART port from a given buffer and length,
*
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data and the break signal have been sent out.
@ -641,9 +652,10 @@ esp_err_t uart_flush(uart_port_t uart_num);
esp_err_t uart_flush_input(uart_port_t uart_num);
/**
* @brief UART get RX ring buffer cached data length
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
* @brief UART get RX ring buffer cached data length
*
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
@ -652,9 +664,9 @@ esp_err_t uart_flush_input(uart_port_t uart_num);
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);
/**
* @brief UART disable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detects a series of one same character, the interrupt will be triggered.
* @brief UART disable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detects a series of one same character, the interrupt will be triggered.
*
* @param uart_num UART port number.
*
@ -737,6 +749,96 @@ int uart_pattern_get_pos(uart_port_t uart_num);
*/
esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length);
/**
* @brief UART set communication mode
* @note This function must be executed after uart_driver_install(), when the driver object is initialized.
* @param uart_num Uart number to configure
* @param mode UART UART mode to set
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);
/**
* @brief UART set threshold timeout for TOUT feature
*
* @param uart_num Uart number to configure
* @param tout_thresh This parameter defines timeout threshold in uart symbol periods. The maximum value of threshold is 126.
* tout_thresh = 1, defines TOUT interrupt timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
* If the time is expired the UART_RXFIFO_TOUT_INT interrupt is triggered. If tout_thresh == 0,
* the TOUT feature is disabled.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_INVALID_STATE Driver is not installed
*/
esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
/**
* @brief Returns collision detection flag for RS485 mode
* Function returns the collision detection flag into variable pointed by collision_flag.
* *collision_flag = true, if collision detected else it is equal to false.
* This function should be executed when actual transmission is completed (after uart_write_bytes()).
*
* @param uart_num Uart number to configure
* @param collision_flag Pointer to variable of type bool to return collision flag.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag);
/**
* @brief Set the number of RX pin signal edges for light sleep wakeup
*
* UART can be used to wake up the system from light sleep. This feature works
* by counting the number of positive edges on RX pin and comparing the count to
* the threshold. When the count exceeds the threshold, system is woken up from
* light sleep. This function allows setting the threshold value.
*
* Stop bit and parity bits (if enabled) also contribute to the number of edges.
* For example, letter 'a' with ASCII code 97 is encoded as 010001101 on the wire
* (with 8n1 configuration), start and stop bits included. This sequence has 3
* positive edges (transitions from 0 to 1). Therefore, to wake up the system
* when 'a' is sent, set wakeup_threshold=3.
*
* The character that triggers wakeup is not received by UART (i.e. it can not
* be obtained from UART FIFO). Depending on the baud rate, a few characters
* after that will also not be received. Note that when the chip enters and exits
* light sleep mode, APB frequency will be changing. To make sure that UART has
* correct baud rate all the time, select REF_TICK as UART clock source,
* by setting use_ref_tick field in uart_config_t to true.
*
* @note in ESP32, UART2 does not support light sleep wakeup feature.
*
* @param uart_num UART number
* @param wakeup_threshold number of RX edges for light sleep wakeup, value is 3 .. 0x3ff.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if uart_num is incorrect or wakeup_threshold is
* outside of [3, 0x3ff] range.
*/
esp_err_t uart_set_wakeup_threshold(uart_port_t uart_num, int wakeup_threshold);
/**
* @brief Get the number of RX pin signal edges for light sleep wakeup.
*
* See description of uart_set_wakeup_threshold for the explanation of UART
* wakeup feature.
*
* @param uart_num UART number
* @param[out] out_wakeup_threshold output, set to the current value of wakeup
* threshold for the given UART.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if out_wakeup_threshold is NULL
*/
esp_err_t uart_get_wakeup_threshold(uart_port_t uart_num, int* out_wakeup_threshold);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,101 @@
/*
* This file is subject to the terms and conditions defined in
* file 'LICENSE', which is part of this source code package.
* Tuan PM <tuanpm at live dot com>
*/
#ifndef _MQTT_CLIENT_H_
#define _MQTT_CLIENT_H_
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "esp_err.h"
#include "mqtt_config.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct esp_mqtt_client* esp_mqtt_client_handle_t;
typedef enum {
MQTT_EVENT_ERROR = 0,
MQTT_EVENT_CONNECTED,
MQTT_EVENT_DISCONNECTED,
MQTT_EVENT_SUBSCRIBED,
MQTT_EVENT_UNSUBSCRIBED,
MQTT_EVENT_PUBLISHED,
MQTT_EVENT_DATA,
} esp_mqtt_event_id_t;
typedef enum {
MQTT_TRANSPORT_UNKNOWN = 0x0,
MQTT_TRANSPORT_OVER_TCP, /*!< MQTT over TCP, using scheme: ``mqtt`` */
MQTT_TRANSPORT_OVER_SSL, /*!< MQTT over SSL, using scheme: ``mqtts`` */
MQTT_TRANSPORT_OVER_WS, /*!< MQTT over Websocket, using scheme:: ``ws`` */
MQTT_TRANSPORT_OVER_WSS /*!< MQTT over Websocket Secure, using scheme: ``wss`` */
} esp_mqtt_transport_t;
/**
* MQTT event configuration structure
*/
typedef struct {
esp_mqtt_event_id_t event_id; /*!< MQTT event type */
esp_mqtt_client_handle_t client; /*!< MQTT client handle for this event */
void *user_context; /*!< User context passed from MQTT client config */
char *data; /*!< Data asociated with this event */
int data_len; /*!< Lenght of the data for this event */
int total_data_len; /*!< Total length of the data (longer data are supplied with multiple events) */
int current_data_offset; /*!< Actual offset for the data asociated with this event */
char *topic; /*!< Topic asociated with this event */
int topic_len; /*!< Length of the topic for this event asociated with this event */
int msg_id; /*!< MQTT messaged id of message */
} esp_mqtt_event_t;
typedef esp_mqtt_event_t* esp_mqtt_event_handle_t;
typedef esp_err_t (* mqtt_event_callback_t)(esp_mqtt_event_handle_t event);
/**
* MQTT client configuration structure
*/
typedef struct {
mqtt_event_callback_t event_handle; /*!< handle for MQTT events */
const char *host; /*!< MQTT server domain (ipv4 as string) */
const char *uri; /*!< Complete MQTT broker URI */
uint32_t port; /*!< MQTT server port */
const char *client_id; /*!< default client id is ``ESP32_%CHIPID%`` where %CHIPID% are last 3 bytes of MAC address in hex format */
const char *username; /*!< MQTT username */
const char *password; /*!< MQTT password */
const char *lwt_topic; /*!< LWT (Last Will and Testament) message topic (NULL by default) */
const char *lwt_msg; /*!< LWT message (NULL by default) */
int lwt_qos; /*!< LWT message qos */
int lwt_retain; /*!< LWT retained message flag */
int lwt_msg_len; /*!< LWT message length */
int disable_clean_session; /*!< mqtt clean session, default clean_session is true */
int keepalive; /*!< mqtt keepalive, default is 120 seconds */
bool disable_auto_reconnect; /*!< this mqtt client will reconnect to server (when errors/disconnect). Set disable_auto_reconnect=true to disable */
void *user_context; /*!< pass user context to this option, then can receive that context in ``event->user_context`` */
int task_prio; /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */
int task_stack; /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */
int buffer_size; /*!< size of MQTT send/receive buffer, default is 1024 */
const char *cert_pem; /*!< pointer to CERT file for server verify (with SSL), default is NULL, not required to verify the server */
esp_mqtt_transport_t transport; /*!< overrides URI transport */
} esp_mqtt_client_config_t;
esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config);
esp_err_t esp_mqtt_client_set_uri(esp_mqtt_client_handle_t client, const char *uri);
esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client);
esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client);
esp_err_t esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos);
esp_err_t esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic);
int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain);
esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif

View File

@ -0,0 +1,81 @@
/*
* This file is subject to the terms and conditions defined in
* file 'LICENSE', which is part of this source code package.
* Tuan PM <tuanpm at live dot com>
*/
#ifndef _MQTT_CONFIG_H_
#define _MQTT_CONFIG_H_
#include "sdkconfig.h"
#define MQTT_PROTOCOL_311 CONFIG_MQTT_PROTOCOL_311
#define MQTT_RECONNECT_TIMEOUT_MS (10*1000)
#if CONFIG_MQTT_BUFFER_SIZE
#define MQTT_BUFFER_SIZE_BYTE CONFIG_MQTT_BUFFER_SIZE
#else
#define MQTT_BUFFER_SIZE_BYTE 1024
#endif
#define MQTT_MAX_HOST_LEN 64
#define MQTT_MAX_CLIENT_LEN 32
#define MQTT_MAX_USERNAME_LEN 32
#define MQTT_MAX_PASSWORD_LEN 65
#define MQTT_MAX_LWT_TOPIC 32
#define MQTT_MAX_LWT_MSG 128
#define MQTT_TASK_PRIORITY 5
#if CONFIG_MQTT_TASK_STACK_SIZE
#define MQTT_TASK_STACK CONFIG_MQTT_TASK_STACK_SIZE
#else
#define MQTT_TASK_STACK (6*1024)
#endif
#define MQTT_KEEPALIVE_TICK (120)
#define MQTT_CMD_QUEUE_SIZE (10)
#define MQTT_NETWORK_TIMEOUT_MS (10000)
#ifdef CONFIG_MQTT_TCP_DEFAULT_PORT
#define MQTT_TCP_DEFAULT_PORT CONFIG_MQTT_TCP_DEFAULT_PORT
#else
#define MQTT_TCP_DEFAULT_PORT 1883
#endif
#ifdef CONFIG_MQTT_SSL_DEFAULT_PORT
#define MQTT_SSL_DEFAULT_PORT CONFIG_MQTT_SSL_DEFAULT_PORT
#else
#define MQTT_SSL_DEFAULT_PORT 8883
#endif
#ifdef CONFIG_MQTT_WS_DEFAULT_PORT
#define MQTT_WS_DEFAULT_PORT CONFIG_MQTT_WS_DEFAULT_PORT
#else
#define MQTT_WS_DEFAULT_PORT 80
#endif
#ifdef MQTT_WSS_DEFAULT_PORT
#define MQTT_WSS_DEFAULT_PORT CONFIG_MQTT_WSS_DEFAULT_PORT
#else
#define MQTT_WSS_DEFAULT_PORT 443
#endif
#define MQTT_CORE_SELECTION_ENABLED CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED
#ifdef CONFIG_MQTT_USE_CORE_0
#define MQTT_TASK_CORE 0
#else
#ifdef CONFIG_MQTT_USE_CORE_1
#define MQTT_TASK_CORE 1
#else
#define MQTT_TASK_CORE 0
#endif
#endif
#define MQTT_ENABLE_SSL CONFIG_MQTT_TRANSPORT_SSL
#define MQTT_ENABLE_WS CONFIG_MQTT_TRANSPORT_WEBSOCKET
#define MQTT_ENABLE_WSS CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE
#define OUTBOX_EXPIRED_TIMEOUT_MS (30*1000)
#define OUTBOX_MAX_SIZE (4*1024)
#endif

View File

@ -18,7 +18,6 @@
#include <sys/socket.h>
#include <fcntl.h>
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/esp_debug.h"
@ -48,12 +47,14 @@ typedef struct esp_tls_cfg {
const unsigned char *cacert_pem_buf; /*!< Certificate Authority's certificate in a buffer */
const unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate
unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate
pointed to by cacert_pem_buf */
bool non_block; /*!< Configure non-blocking mode. If set to true the
underneath socket will be configured in non
blocking mode after tls session is established */
int timeout_ms; /*!< Network timeout in milliseconds */
} esp_tls_cfg_t;
/**
@ -165,6 +166,21 @@ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t data
*/
void esp_tls_conn_delete(esp_tls_t *tls);
/**
* @brief Return the number of application data bytes remaining to be
* read from the current record
*
* This API is a wrapper over mbedtls's mbedtls_ssl_get_bytes_avail() API.
*
* @param[in] tls pointer to esp-tls as esp-tls handle.
*
* @return
* - -1 in case of invalid arg
* - bytes available in the application data
* record read buffer
*/
size_t esp_tls_get_bytes_avail(esp_tls_t *tls);
#ifdef __cplusplus
}
#endif

View File

@ -31,8 +31,10 @@ extern "C" {
* Pass a pointer to this structure as an argument to esp_pm_configure function.
*/
typedef struct {
rtc_cpu_freq_t max_cpu_freq; /*!< Maximum CPU frequency to use */
rtc_cpu_freq_t min_cpu_freq; /*!< Minimum CPU frequency to use when no frequency locks are taken */
rtc_cpu_freq_t max_cpu_freq __attribute__((deprecated)); /*!< Maximum CPU frequency to use. Deprecated, use max_freq_mhz instead. */
int max_freq_mhz; /*!< Maximum CPU frequency, in MHz */
rtc_cpu_freq_t min_cpu_freq __attribute__((deprecated)); /*!< Minimum CPU frequency to use when no frequency locks are taken. Deprecated, use min_freq_mhz instead. */
int min_freq_mhz; /*!< Minimum CPU frequency to use when no locks are taken, in MHz */
bool light_sleep_enable; /*!< Enter light sleep when no locks are taken */
} esp_pm_config_esp32_t;

View File

@ -62,6 +62,17 @@ int esp_clk_cpu_freq(void);
*/
int esp_clk_apb_freq(void);
/**
* @brief Return frequency of the main XTAL
*
* Frequency of the main XTAL can be either auto-detected or set at compile
* time (see CONFIG_ESP32_XTAL_FREQ_SEL sdkconfig option). In both cases, this
* function returns the actual value at run time.
*
* @return XTAL frequency, in Hz
*/
int esp_clk_xtal_freq(void);
/**
* @brief Read value of RTC counter, converting it to microseconds

View File

@ -27,20 +27,20 @@ typedef int32_t esp_err_t;
#define ESP_OK 0 /*!< esp_err_t value indicating success (no error) */
#define ESP_FAIL -1 /*!< Generic esp_err_t code indicating failure */
#define ESP_ERR_NO_MEM 0x101 /*!< Out of memory */
#define ESP_ERR_INVALID_ARG 0x102 /*!< Invalid argument */
#define ESP_ERR_INVALID_STATE 0x103 /*!< Invalid state */
#define ESP_ERR_INVALID_SIZE 0x104 /*!< Invalid size */
#define ESP_ERR_NOT_FOUND 0x105 /*!< Requested resource not found */
#define ESP_ERR_NOT_SUPPORTED 0x106 /*!< Operation or feature not supported */
#define ESP_ERR_TIMEOUT 0x107 /*!< Operation timed out */
#define ESP_ERR_NO_MEM 0x101 /*!< Out of memory */
#define ESP_ERR_INVALID_ARG 0x102 /*!< Invalid argument */
#define ESP_ERR_INVALID_STATE 0x103 /*!< Invalid state */
#define ESP_ERR_INVALID_SIZE 0x104 /*!< Invalid size */
#define ESP_ERR_NOT_FOUND 0x105 /*!< Requested resource not found */
#define ESP_ERR_NOT_SUPPORTED 0x106 /*!< Operation or feature not supported */
#define ESP_ERR_TIMEOUT 0x107 /*!< Operation timed out */
#define ESP_ERR_INVALID_RESPONSE 0x108 /*!< Received response was invalid */
#define ESP_ERR_INVALID_CRC 0x109 /*!< CRC or checksum was invalid */
#define ESP_ERR_INVALID_CRC 0x109 /*!< CRC or checksum was invalid */
#define ESP_ERR_INVALID_VERSION 0x10A /*!< Version was invalid */
#define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */
#define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */
/**
* @brief Returns string for esp_err_t error codes

File diff suppressed because it is too large Load Diff

View File

@ -34,23 +34,30 @@ extern "C" {
*******************************************************/
typedef struct {
int scan; /**< minimum scan times before being a root, default:10 */
int vote; /**< max vote times in self-healing, default:10000 */
int vote; /**< max vote times in self-healing, default:1000 */
int fail; /**< parent selection fail times, if the scan times reach this value,
will disconnect with associated children and join self-healing. default:60 */
int monitor_ie; /**< acceptable times of parent ie change before update self ie, default:3 */
device will disconnect with associated children and join self-healing. default:60 */
int monitor_ie; /**< acceptable times of parent networking IE change before update its own networking IE. default:3 */
} mesh_attempts_t;
typedef struct {
int duration_ms; /* parent weak RSSI monitor duration, if the RSSI continues to be weak during this duration_ms,
will switch to a better parent */
int cnx_rssi; /* RSSI threshold for keeping a good connection with parent */
int select_rssi; /* RSSI threshold for parent selection, should be a value greater than switch_rssi */
int switch_rssi; /* RSSI threshold for action to reselect a better parent */
device will search for a new parent. */
int cnx_rssi; /* RSSI threshold for keeping a good connection with parent.
If set a value greater than -120 dBm, a timer will be armed to monitor parent RSSI at a period time of duration_ms. */
int select_rssi; /* RSSI threshold for parent selection. It should be a value greater than switch_rssi. */
int switch_rssi; /* Disassociate with current parent and switch to a new parent when the RSSI is greater than this set threshold. */
int backoff_rssi; /* RSSI threshold for connecting to the root */
} mesh_switch_parent_t;
typedef struct {
int high;
int medium;
int low;
} mesh_rssi_threshold_t;
/**
* @brief mesh networking IE
* @brief Mesh networking IE
*/
typedef struct {
/**< mesh networking IE head */
@ -58,8 +65,8 @@ typedef struct {
uint8_t len; /**< element length */
uint8_t oui[3]; /**< organization identifier */
/**< mesh networking IE content */
uint8_t type; /** mesh networking IE type */
uint8_t encryped : 1; /**< if mesh networking IE is encrypted */
uint8_t type; /** ESP defined IE type */
uint8_t encryped : 1; /**< whether mesh networking IE is encrypted */
uint8_t version : 7; /**< mesh networking IE version */
/**< content */
uint8_t mesh_type; /**< mesh device type */
@ -73,14 +80,14 @@ typedef struct {
uint16_t root_cap; /**< root capacity */
uint16_t self_cap; /**< self capacity */
uint16_t layer2_cap; /**< layer2 capacity */
uint16_t scan_ap_num; /**< the number of scanned APs */
int8_t rssi; /**< rssi of the parent */
int8_t router_rssi; /**< rssi of the router */
uint16_t scan_ap_num; /**< the number of scanning APs */
int8_t rssi; /**< RSSI of the parent */
int8_t router_rssi; /**< RSSI of the router */
uint8_t flag; /**< flag of networking */
uint8_t rc_addr[6]; /**< root address */
int8_t rc_rssi; /**< root rssi */
int8_t rc_rssi; /**< root RSSI */
uint8_t vote_addr[6]; /**< voter address */
int8_t vote_rssi; /**< vote rssi of the router */
int8_t vote_rssi; /**< vote RSSI of the router */
uint8_t vote_ttl; /**< vote ttl */
uint16_t votes; /**< votes */
uint16_t my_votes; /**< my votes */
@ -93,9 +100,9 @@ typedef struct {
* Function Definitions
*******************************************************/
/**
* @brief set mesh softAP beacon interval
* @brief Set mesh softAP beacon interval
*
* @param interval beacon interval(ms) (100ms ~ 60000ms)
* @param[in] interval beacon interval (msecs) (100 msecs ~ 60000 msecs)
*
* @return
* - ESP_OK
@ -105,9 +112,9 @@ typedef struct {
esp_err_t esp_mesh_set_beacon_interval(int interval_ms);
/**
* @brief get mesh softAP beacon interval
* @brief Get mesh softAP beacon interval
*
* @param interval beacon interval(ms)
* @param[out] interval beacon interval (msecs)
*
* @return
* - ESP_OK
@ -115,9 +122,9 @@ esp_err_t esp_mesh_set_beacon_interval(int interval_ms);
esp_err_t esp_mesh_get_beacon_interval(int *interval_ms);
/**
* @brief set attempts for mesh self-organized networking
* @brief Set attempts for mesh self-organized networking
*
* @param attempts
* @param[in] attempts
*
* @return
* - ESP_OK
@ -126,40 +133,77 @@ esp_err_t esp_mesh_get_beacon_interval(int *interval_ms);
esp_err_t esp_mesh_set_attempts(mesh_attempts_t *attempts);
/**
* @brief get attempts for mesh self-organized networking
* @brief Get attempts for mesh self-organized networking
*
* @param attempts
* @param[out] attempts
*
* @return
* - ESP_OK
* - ESP_FAIL
* - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_get_attempts(mesh_attempts_t *attempts);
/**
* @brief set parameters for parent switch
* @brief Set parameters for parent switch
*
* @param paras parameters for parent switch
* @param[in] paras parameters for parent switch
*
* @return
* - ESP_OK
* - ESP_FAIL
* - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras);
/**
* @brief get parameters for parent switch
* @brief Get parameters for parent switch
*
* @param paras parameters for parent switch
* @param[out] paras parameters for parent switch
*
* @return
* - ESP_OK
* - ESP_FAIL
* - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras);
/**
* @brief print the number of txQ waiting
* @brief Set RSSI threshold
* - The default high RSSI threshold value is -78 dBm.
* - The default medium RSSI threshold value is -82 dBm.
* - The default low RSSI threshold value is -85 dBm.
*
* @param[in] threshold RSSI threshold
*
* @return
* - ESP_OK
* - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_set_rssi_threshold(const mesh_rssi_threshold_t *threshold);
/**
* @brief Get RSSI threshold
*
* @param[out] threshold RSSI threshold
*
* @return
* - ESP_OK
* - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_get_rssi_threshold(mesh_rssi_threshold_t *threshold);
/**
* @brief Enable the minimum rate to 6 Mbps
*
* @attention This API shall be called before Wi-Fi is started.
*
* @param[in] is_6m enable or not
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_set_6m_rate(bool is_6m);
/**
* @brief Print the number of txQ waiting
*
* @return
* - ESP_OK
@ -168,7 +212,7 @@ esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras);
esp_err_t esp_mesh_print_txQ_waiting(void);
/**
* @brief print the number of rxQ waiting
* @brief Print the number of rxQ waiting
*
* @return
* - ESP_OK
@ -177,9 +221,9 @@ esp_err_t esp_mesh_print_txQ_waiting(void);
esp_err_t esp_mesh_print_rxQ_waiting(void);
/**
* @brief set passive scan time
* @brief Set passive scan time
*
* @param interval_ms passive scan time(ms)
* @param[in] interval_ms passive scan time (msecs)
*
* @return
* - ESP_OK
@ -189,12 +233,35 @@ esp_err_t esp_mesh_print_rxQ_waiting(void);
esp_err_t esp_mesh_set_passive_scan_time(int time_ms);
/**
* @brief get passive scan time
* @brief Get passive scan time
*
* @return interval_ms passive scan time(ms)
* @return interval_ms passive scan time (msecs)
*/
int esp_mesh_get_passive_scan_time(void);
/**
* @brief Set announce interval
* - The default short interval is 500 milliseconds.
* - The default long interval is 3000 milliseconds.
*
* @param[in] short_ms shall be greater than the default value
* @param[in] long_ms shall be greater than the default value
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_set_announce_interval(int short_ms, int long_ms);
/**
* @brief Get announce interval
*
* @param[out] short_ms short interval
* @param[out] long_ms long interval
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_get_announce_interval(int *short_ms, int *long_ms);
#ifdef __cplusplus
}

View File

@ -61,12 +61,6 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags);
*/
void esp_clear_watchpoint(int no);
/**
* @brief Stops panic WDT
*/
void esp_panic_wdt_stop(void);
/**
* @brief Checks stack pointer
*/

View File

@ -202,6 +202,10 @@ esp_err_t esp_modem_sleep_exit(modem_sleep_module_t module);
/**
* @brief Register module to make it be able to require to enter/exit modem sleep
* Although the module has no sleep function, as long as the module use RF,
* it must call esp_modem_sleep_regsiter. Otherwise, other modules with sleep
* function will disable RF without checking the module which doesn't call
* esp_modem_sleep_regsiter.
*/
esp_err_t esp_modem_sleep_register(modem_sleep_module_t module);

View File

@ -56,11 +56,14 @@ typedef enum {
*/
typedef enum {
ESP_SLEEP_WAKEUP_UNDEFINED, //!< In case of deep sleep, reset was not caused by exit from deep sleep
ESP_SLEEP_WAKEUP_ALL, //!< Not a wakeup cause, used to disable all wakeup sources with esp_sleep_disable_wakeup_source
ESP_SLEEP_WAKEUP_EXT0, //!< Wakeup caused by external signal using RTC_IO
ESP_SLEEP_WAKEUP_EXT1, //!< Wakeup caused by external signal using RTC_CNTL
ESP_SLEEP_WAKEUP_TIMER, //!< Wakeup caused by timer
ESP_SLEEP_WAKEUP_TOUCHPAD, //!< Wakeup caused by touchpad
ESP_SLEEP_WAKEUP_ULP, //!< Wakeup caused by ULP program
ESP_SLEEP_WAKEUP_GPIO, //!< Wakeup caused by GPIO (light sleep only)
ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART (light sleep only)
} esp_sleep_source_t;
/* Leave this type define for compatibility */
@ -189,6 +192,43 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
*/
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);
/**
* @brief Enable wakeup from light sleep using GPIOs
*
* Each GPIO supports wakeup function, which can be triggered on either low level
* or high level. Unlike EXT0 and EXT1 wakeup sources, this method can be used
* both for all IOs: RTC IOs and digital IOs. It can only be used to wakeup from
* light sleep though.
*
* To enable wakeup, first call gpio_wakeup_enable, specifying gpio number and
* wakeup level, for each GPIO which is used for wakeup.
* Then call this function to enable wakeup feature.
*
* @note In revisions 0 and 1 of the ESP32, GPIO wakeup source
* can not be used together with touch or ULP wakeup sources.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/
esp_err_t esp_sleep_enable_gpio_wakeup();
/**
* @brief Enable wakeup from light sleep using UART
*
* Use uart_set_wakeup_threshold function to configure UART wakeup threshold.
*
* Wakeup from light sleep takes some time, so not every character sent
* to the UART can be received by the application.
*
* @note ESP32 does not support wakeup from UART2.
*
* @param uart_num UART port to wake up from
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if wakeup from given UART is not supported
*/
esp_err_t esp_sleep_enable_uart_wakeup(int uart_num);
/**
* @brief Get the bit mask of GPIOs which caused wakeup (ext1)
@ -265,9 +305,9 @@ void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated)
/**
* @brief Get the source which caused wakeup from sleep
* @brief Get the wakeup source which caused wakeup from sleep
*
* @return wakeup cause, or ESP_DEEP_SLEEP_WAKEUP_UNDEFINED if reset happened for reason other than deep sleep wakeup
* @return cause of wake up from last sleep (deep sleep or light sleep)
*/
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause();
@ -319,6 +359,12 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
*/
void esp_default_wake_deep_sleep(void);
/**
* @brief Disable logging from the ROM code after deep sleep.
*
* Using LSB of RTC_STORE4.
*/
void esp_deep_sleep_disable_rom_logging(void);
#ifdef __cplusplus
}

View File

@ -42,7 +42,7 @@ typedef enum {
*
* @param status Status of SmartConfig:
* - SC_STATUS_GETTING_SSID_PSWD : pdata is a pointer of smartconfig_type_t, means config type.
* - SC_STATUS_LINK : pdata is a pointer of struct station_config.
* - SC_STATUS_LINK : pdata is a pointer to wifi_config_t.
* - SC_STATUS_LINK_OVER : pdata is a pointer of phone's IP address(4 bytes) if pdata unequal NULL.
* - otherwise : parameter void *pdata is NULL.
* @param pdata According to the different status have different values.

View File

@ -18,8 +18,37 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
typedef enum {
ESP_SPIRAM_VOLT_3V3 = 0, /*!< SPI RAM voltage is 3.3v */
ESP_SPIRAM_VOLT_1V8 = 1, /*!< SPI RAM voltage is 1.8v */
ESP_SPIRAM_VOLT_INVALID, /*!< SPI RAM voltage is invalid*/
} esp_spiram_volt_t;
typedef enum {
ESP_SPIRAM_SIZE_32MBITS = 0, /*!< SPI RAM size is 32 MBits */
ESP_SPIRAM_SIZE_64MBITS = 1, /*!< SPI RAM size is 64 MBits */
ESP_SPIRAM_SIZE_INVALID, /*!< SPI RAM size is invalid */
} esp_spiram_size_t;
/**
* @brief get SPI RAM voltage
* @return
* - ESP_SPIRAM_VOLT_INVALID if SPI RAM not enabled or not valid.
* - SPI RAM voltage
*/
esp_spiram_volt_t esp_spiram_get_chip_volt();
/**
* @brief get SPI RAM size
* @return
* - ESP_SPIRAM_SIZE_INVALID if SPI RAM not enabled or not valid
* - SPI RAM size
*/
esp_spiram_size_t esp_spiram_get_chip_size();
/**
* @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
*

Some files were not shown because too many files have changed in this diff Show More