diff --git a/platform.txt b/platform.txt index 8364a33f..09261111 100644 --- a/platform.txt +++ b/platform.txt @@ -13,7 +13,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/bt" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/wpa_supplicant" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/lwip" +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/bt" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/wpa_supplicant" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/lwip" compiler.c.cmd=xtensa-esp32-elf-gcc compiler.c.flags=-std=gnu99 -Os -g3 -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 @@ -26,7 +26,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 -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static -Wl,--undefined=uxTopUsedPriority -compiler.c.elf.libs=-lapp_update -lbootloader_support -lbt -lbtdm_app -lc -lc_nano -lcoexist -lcore -ldriver -lesp32 -lethernet -lexpat -lfreertos -lhal -ljson -llog -llwip -lm -lmbedtls -lmicro-ecc -lnet80211 -lnewlib -lnghttp -lnvs_flash -lopenssl -lphy -lpp -lrtc -lsmartconfig -lspi_flash -ltcpip_adapter -lulp -lvfs -lwpa -lwpa2 -lwpa_supplicant -lwps -lxtensa-debug-module -lgcc +compiler.c.elf.libs=-lapp_update -lbootloader_support -lbt -lbtdm_app -lc -lc_nano -lcoap -lcoexist -lcore -lcxx -ldriver -lesp32 -lethernet -lexpat -lfatfs -lfreertos -lhal -ljson -llog -llwip -lm -lmbedtls -lmdns -lmicro-ecc -lnet80211 -lnewlib -lnghttp -lnvs_flash -lopenssl -lphy -lpp -lrtc -lsdmmc -lsmartconfig -lspi_flash -ltcpip_adapter -lulp -lvfs -lwpa -lwpa2 -lwpa_supplicant -lwps -lxtensa-debug-module -lgcc -lstdc++ compiler.as.cmd=xtensa-esp32-elf-as diff --git a/tools/sdk/bin/bootloader.bin b/tools/sdk/bin/bootloader.bin index 8a009baa..8aa1cb39 100644 Binary files a/tools/sdk/bin/bootloader.bin and b/tools/sdk/bin/bootloader.bin differ diff --git a/tools/sdk/include/bt/bt.h b/tools/sdk/include/bt/bt.h index 310fdcb9..926ecfad 100644 --- a/tools/sdk/include/bt/bt.h +++ b/tools/sdk/include/bt/bt.h @@ -29,35 +29,35 @@ extern "C" { * * This function should be called only once, before any other BT functions are called. */ -void bt_controller_init(void); +void esp_bt_controller_init(void); -/** @brief vhci_host_callback +/** @brief esp_vhci_host_callback * used for vhci call host function to notify what host need to do */ -typedef struct vhci_host_callback { +typedef struct esp_vhci_host_callback { void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ -} vhci_host_callback_t; +} esp_vhci_host_callback_t; -/** @brief API_vhci_host_check_send_available +/** @brief esp_vhci_host_check_send_available * used for check actively if the host can send packet to controller or not. * @return true for ready to send, false means cannot send packet */ -bool API_vhci_host_check_send_available(void); +bool esp_vhci_host_check_send_available(void); -/** @brief API_vhci_host_send_packet +/** @brief esp_vhci_host_send_packet * host send packet to controller * @param data the packet point *,@param len the packet length */ -void API_vhci_host_send_packet(uint8_t *data, uint16_t len); +void esp_vhci_host_send_packet(uint8_t *data, uint16_t len); -/** @brief API_vhci_host_register_callback +/** @brief esp_vhci_host_register_callback * register the vhci referece callback, the call back * struct defined by vhci_host_callback structure. - * @param callback vhci_host_callback type variable + * @param callback esp_vhci_host_callback type variable */ -void API_vhci_host_register_callback(const vhci_host_callback_t *callback); +void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); #ifdef __cplusplus } diff --git a/tools/sdk/include/coap/coap/address.h b/tools/sdk/include/coap/coap/address.h new file mode 100644 index 00000000..85db2046 --- /dev/null +++ b/tools/sdk/include/coap/coap/address.h @@ -0,0 +1,152 @@ +/* + * address.h -- representation of network addresses + * + * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file address.h + * @brief Representation of network addresses + */ + +#ifndef _COAP_ADDRESS_H_ +#define _COAP_ADDRESS_H_ + +#include +#include +#include +#include +#include "libcoap.h" + +#ifdef WITH_LWIP +#include + +typedef struct coap_address_t { + uint16_t port; + ip_addr_t addr; +} coap_address_t; + +#define _coap_address_equals_impl(A, B) (!!ip_addr_cmp(&(A)->addr,&(B)->addr)) + +#define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) + +#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr) +#endif /* WITH_LWIP */ + +#ifdef WITH_CONTIKI +#include "uip.h" + +typedef struct coap_address_t { + uip_ipaddr_t addr; + unsigned short port; +} coap_address_t; + +#define _coap_address_equals_impl(A,B) \ + ((A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) + +/** @todo implementation of _coap_address_isany_impl() for Contiki */ +#define _coap_address_isany_impl(A) 0 + +#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) +#endif /* WITH_CONTIKI */ + +#ifdef WITH_POSIX +/** multi-purpose address abstraction */ +typedef struct coap_address_t { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_storage st; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +} coap_address_t; + +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +int coap_address_equals(const coap_address_t *a, const coap_address_t *b); + +static inline int +_coap_address_isany_impl(const coap_address_t *a) { + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return a->addr.sin.sin_addr.s_addr == INADDR_ANY; + case AF_INET6: + return memcmp(&in6addr_any, + &a->addr.sin6.sin6_addr, + sizeof(in6addr_any)) == 0; + default: + ; + } + + return 0; +} +#endif /* WITH_POSIX */ + +/** + * Resets the given coap_address_t object @p addr to its default values. In + * particular, the member size must be initialized to the available size for + * storing addresses. + * + * @param addr The coap_address_t object to initialize. + */ +static inline void +coap_address_init(coap_address_t *addr) { + assert(addr); + memset(addr, 0, sizeof(coap_address_t)); +#ifdef WITH_POSIX + /* lwip and Contiki have constant address sizes and doesn't need the .size part */ + addr->size = sizeof(addr->addr); +#endif +} + +#ifndef WITH_POSIX +/** + * Compares given address objects @p a and @p b. This function returns @c 1 if + * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be + * @c NULL; + */ +static inline int +coap_address_equals(const coap_address_t *a, const coap_address_t *b) { + assert(a); assert(b); + return _coap_address_equals_impl(a, b); +} +#endif + +/** + * Checks if given address object @p a denotes the wildcard address. This + * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p + * a must not be @c NULL; + */ +static inline int +coap_address_isany(const coap_address_t *a) { + assert(a); + return _coap_address_isany_impl(a); +} + +#ifdef WITH_POSIX +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +int coap_is_mcast(const coap_address_t *a); +#else /* WITH_POSIX */ +/** + * Checks if given address @p a denotes a multicast address. This function + * returns @c 1 if @p a is multicast, @c 0 otherwise. + */ +static inline int +coap_is_mcast(const coap_address_t *a) { + return a && _coap_is_mcast_impl(a); +} +#endif /* WITH_POSIX */ + +#endif /* _COAP_ADDRESS_H_ */ diff --git a/tools/sdk/include/coap/coap/async.h b/tools/sdk/include/coap/coap/async.h new file mode 100644 index 00000000..0c36defa --- /dev/null +++ b/tools/sdk/include/coap/coap/async.h @@ -0,0 +1,146 @@ +/* + * async.h -- state management for asynchronous messages + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file async.h + * @brief State management for asynchronous messages + */ + +#ifndef _COAP_ASYNC_H_ +#define _COAP_ASYNC_H_ + +#include "net.h" + +#ifndef WITHOUT_ASYNC + +/** + * @defgroup coap_async Asynchronous Messaging + * @{ + * Structure for managing asynchronous state of CoAP resources. A + * coap_resource_t object holds a list of coap_async_state_t objects that can be + * used to generate a separate response in case a result of an operation cannot + * be delivered in time, or the resource has been explicitly subscribed to with + * the option @c observe. + */ +typedef struct coap_async_state_t { + unsigned char flags; /**< holds the flags to control behaviour */ + + /** + * Holds the internal time when the object was registered with a + * resource. This field will be updated whenever + * coap_register_async() is called for a specific resource. + */ + coap_tick_t created; + + /** + * This field can be used to register opaque application data with the + * asynchronous state object. + */ + void *appdata; + unsigned short message_id; /**< id of last message seen */ + coap_tid_t id; /**< transaction id */ + struct coap_async_state_t *next; /**< internally used for linking */ + coap_address_t peer; /**< the peer to notify */ + size_t tokenlen; /**< length of the token */ + unsigned char token[]; /**< the token to use in a response */ +} coap_async_state_t; + +/* Definitions for Async Status Flags These flags can be used to control the + * behaviour of asynchronous response generation. + */ +#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */ +#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */ +#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */ + +/** release application data on destruction */ +#define COAP_ASYNC_RELEASE_DATA 0x08 + +/** + * Allocates a new coap_async_state_t object and fills its fields according to + * the given @p request. The @p flags are used to control generation of empty + * ACK responses to stop retransmissions and to release registered @p data when + * the resource is deleted by coap_free_async(). This function returns a pointer + * to the registered coap_async_t object or @c NULL on error. Note that this + * function will return @c NULL in case that an object with the same identifier + * is already registered. + * + * @param context The context to use. + * @param peer The remote peer that is to be asynchronously notified. + * @param request The request that is handled asynchronously. + * @param flags Flags to control state management. + * @param data Opaque application data to register. Note that the + * storage occupied by @p data is released on destruction + * only if flag COAP_ASYNC_RELEASE_DATA is set. + * + * @return A pointer to the registered coap_async_state_t object or @c + * NULL in case of an error. + */ +coap_async_state_t * +coap_register_async(coap_context_t *context, + coap_address_t *peer, + coap_pdu_t *request, + unsigned char flags, + void *data); + +/** + * Removes the state object identified by @p id from @p context. The removed + * object is returned in @p s, if found. Otherwise, @p s is undefined. This + * function returns @c 1 if the object was removed, @c 0 otherwise. Note that + * the storage allocated for the stored object is not released by this + * functions. You will have to call coap_free_async() to do so. + * + * @param context The context where the async object is registered. + * @param id The identifier of the asynchronous transaction. + * @param s Will be set to the object identified by @p id after removal. + * + * @return @c 1 if object was removed and @p s updated, or @c 0 if no + * object was found with the given id. @p s is valid only if the + * return value is @c 1. + */ +int coap_remove_async(coap_context_t *context, + coap_tid_t id, + coap_async_state_t **s); + +/** + * Releases the memory that was allocated by coap_async_state_init() for the + * object @p s. The registered application data will be released automatically + * if COAP_ASYNC_RELEASE_DATA is set. + * + * @param state The object to delete. + */ +void +coap_free_async(coap_async_state_t *state); + +/** + * Retrieves the object identified by @p id from the list of asynchronous + * transactions that are registered with @p context. This function returns a + * pointer to that object or @c NULL if not found. + * + * @param context The context where the asynchronous objects are registered + * with. + * @param id The id of the object to retrieve. + * + * @return A pointer to the object identified by @p id or @c NULL if + * not found. + */ +coap_async_state_t *coap_find_async(coap_context_t *context, coap_tid_t id); + +/** + * Updates the time stamp of @p s. + * + * @param s The state object to update. + */ +static inline void +coap_touch_async(coap_async_state_t *s) { coap_ticks(&s->created); } + +/** @} */ + +#endif /* WITHOUT_ASYNC */ + +#endif /* _COAP_ASYNC_H_ */ diff --git a/tools/sdk/include/coap/coap/bits.h b/tools/sdk/include/coap/coap/bits.h new file mode 100644 index 00000000..0b269166 --- /dev/null +++ b/tools/sdk/include/coap/coap/bits.h @@ -0,0 +1,78 @@ +/* + * bits.h -- bit vector manipulation + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file bits.h + * @brief Bit vector manipulation + */ + +#ifndef _COAP_BITS_H_ +#define _COAP_BITS_H_ + +#include + +/** + * Sets the bit @p bit in bit-vector @p vec. This function returns @c 1 if bit + * was set or @c -1 on error (i.e. when the given bit does not fit in the + * vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to set in @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +inline static int +bits_setb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + *(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07)); + return 1; +} + +/** + * Clears the bit @p bit from bit-vector @p vec. This function returns @c 1 if + * bit was cleared or @c -1 on error (i.e. when the given bit does not fit in + * the vector). + * + * @param vec The bit-vector to change. + * @param size The size of @p vec in bytes. + * @param bit The bit to clear from @p vec. + * + * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. + */ +inline static int +bits_clrb(uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + *(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07))); + return 1; +} + +/** + * Gets the status of bit @p bit from bit-vector @p vec. This function returns + * @c 1 if the bit is set, @c 0 otherwise (even in case of an error). + * + * @param vec The bit-vector to read from. + * @param size The size of @p vec in bytes. + * @param bit The bit to get from @p vec. + * + * @return @c 1 if the bit is set, @c 0 otherwise. + */ +inline static int +bits_getb(const uint8_t *vec, size_t size, uint8_t bit) { + if (size <= (bit >> 3)) + return -1; + + return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0; +} + +#endif /* _COAP_BITS_H_ */ diff --git a/tools/sdk/include/coap/coap/block.h b/tools/sdk/include/coap/coap/block.h new file mode 100644 index 00000000..9ce00311 --- /dev/null +++ b/tools/sdk/include/coap/coap/block.h @@ -0,0 +1,137 @@ +/* + * block.h -- block transfer + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_BLOCK_H_ +#define _COAP_BLOCK_H_ + +#include "encode.h" +#include "option.h" +#include "pdu.h" + +/** + * @defgroup block Block Transfer + * @{ + */ + +#ifndef COAP_MAX_BLOCK_SZX +/** + * The largest value for the SZX component in a Block option. Note that + * 1 << (COAP_MAX_BLOCK_SZX + 4) should not exceed COAP_MAX_PDU_SIZE. + */ +#define COAP_MAX_BLOCK_SZX 4 +#endif /* COAP_MAX_BLOCK_SZX */ + +/** + * Structure of Block options. + */ +typedef struct { + unsigned int num; /**< block number */ + unsigned int m:1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx:3; /**< block size */ +} coap_block_t; + +/** + * Returns the value of the least significant byte of a Block option @p opt. + * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST + * returns @c NULL. + */ +#define COAP_OPT_BLOCK_LAST(opt) \ + (COAP_OPT_LENGTH(opt) ? (COAP_OPT_VALUE(opt) + (COAP_OPT_LENGTH(opt)-1)) : 0) + +/** Returns the value of the More-bit of a Block option @p opt. */ +#define COAP_OPT_BLOCK_MORE(opt) \ + (COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0) + +/** Returns the value of the SZX-field of a Block option @p opt. */ +#define COAP_OPT_BLOCK_SZX(opt) \ + (COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0) + +/** + * Returns the value of field @c num in the given block option @p block_opt. + */ +unsigned int coap_opt_block_num(const coap_opt_t *block_opt); + +/** + * Checks if more than @p num blocks are required to deliver @p data_len + * bytes of data for a block size of 1 << (@p szx + 4). + */ +static inline int +coap_more_blocks(size_t data_len, unsigned int num, unsigned short szx) { + return ((num+1) << (szx + 4)) < data_len; +} + +/** Sets the More-bit in @p block_opt */ +static inline void +coap_opt_block_set_m(coap_opt_t *block_opt, int m) { + if (m) + *(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) |= 0x08; + else + *(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) &= ~0x08; +} + +/** + * Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1 + * or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block is + * initialized with values from this option and the function returns the value + * @c 1. Otherwise, @c 0 is returned. + * + * @param pdu The pdu to search for option @p type. + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * COAP_OPTION_BLOCK2). + * @param block The block structure to initilize. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); + +/** + * Writes a block option of type @p type to message @p pdu. If the requested + * block size is too large to fit in @p pdu, it is reduced accordingly. An + * exception is made for the final block when less space is required. The actual + * length of the resource is specified in @p data_length. + * + * This function may change *block to reflect the values written to @p pdu. As + * the function takes into consideration the remaining space @p pdu, no more + * options should be added after coap_write_block_opt() has returned. + * + * @param block The block structure to use. On return, this object is + * updated according to the values that have been written to + * @p pdu. + * @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2. + * @param pdu The message where the block option should be written. + * @param data_length The length of the actual data that will be added the @p + * pdu by calling coap_add_block(). + * + * @return @c 1 on success, or a negative value on error. + */ +int coap_write_block_opt(coap_block_t *block, + unsigned short type, + coap_pdu_t *pdu, + size_t data_length); + +/** + * Adds the @p block_num block of size 1 << (@p block_szx + 4) from source @p + * data to @p pdu. + * + * @param pdu The message to add the block. + * @param len The length of @p data. + * @param data The source data to fill the block with. + * @param block_num The actual block number. + * @param block_szx Encoded size of block @p block_number. + * + * @return @c 1 on success, @c 0 otherwise. + */ +int coap_add_block(coap_pdu_t *pdu, + unsigned int len, + const unsigned char *data, + unsigned int block_num, + unsigned char block_szx); +/**@}*/ + +#endif /* _COAP_BLOCK_H_ */ diff --git a/tools/sdk/include/coap/coap/coap.h b/tools/sdk/include/coap/coap/coap.h new file mode 100644 index 00000000..cbdc9dfc --- /dev/null +++ b/tools/sdk/include/coap/coap/coap.h @@ -0,0 +1,50 @@ +/* Modify head file implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * define operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_H_ +#define _COAP_H_ + +#include "libcoap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "address.h" +#include "async.h" +#include "bits.h" +#include "block.h" +#include "coap_io.h" +#include "coap_time.h" +#include "debug.h" +#include "encode.h" +#include "mem.h" +#include "net.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "resource.h" +#include "str.h" +#include "subscribe.h" +#include "uri.h" +#include "uthash.h" +#include "utlist.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COAP_H_ */ diff --git a/tools/sdk/include/coap/coap/coap.h.in b/tools/sdk/include/coap/coap/coap.h.in new file mode 100644 index 00000000..76ebc5eb --- /dev/null +++ b/tools/sdk/include/coap/coap/coap.h.in @@ -0,0 +1,59 @@ +/* + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_H_ +#define _COAP_H_ + +#include "libcoap.h" + +/* Define the address where bug reports for libcoap should be sent. */ +#define LIBCOAP_PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@ + +/* Define the full name of libcoap. */ +#define LIBCOAP_PACKAGE_NAME @PACKAGE_NAME@ + +/* Define the full name and version of libcoap. */ +#define LIBCOAP_PACKAGE_STRING @PACKAGE_STRING@ + +/* Define the home page for libcoap. */ +#define LIBCOAP_PACKAGE_URL @PACKAGE_URL@ + +/* Define the version of libcoap this file belongs to. */ +#define LIBCOAP_PACKAGE_VERSION @PACKAGE_VERSION@ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "address.h" +#include "async.h" +#include "bits.h" +#include "block.h" +#include "coap_io.h" +#include "coap_time.h" +#include "debug.h" +#include "encode.h" +#include "mem.h" +#include "net.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" +#include "resource.h" +#include "str.h" +#include "subscribe.h" +#include "uri.h" +#include "uthash.h" +#include "utlist.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _COAP_H_ */ diff --git a/tools/sdk/include/coap/coap/coap_io.h b/tools/sdk/include/coap/coap/coap_io.h new file mode 100644 index 00000000..7a48b319 --- /dev/null +++ b/tools/sdk/include/coap/coap/coap_io.h @@ -0,0 +1,167 @@ +/* + * coap_io.h -- Default network I/O functions for libcoap + * + * Copyright (C) 2012-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_IO_H_ +#define _COAP_IO_H_ + +#include +#include + +#include "address.h" + +/** + * Abstract handle that is used to identify a local network interface. + */ +typedef int coap_if_handle_t; + +/** Invalid interface handle */ +#define COAP_IF_INVALID -1 + +struct coap_packet_t; +typedef struct coap_packet_t coap_packet_t; + +struct coap_context_t; + +/** + * Abstraction of virtual endpoint that can be attached to coap_context_t. The + * tuple (handle, addr) must uniquely identify this endpoint. + */ +typedef struct coap_endpoint_t { +#if defined(WITH_POSIX) || defined(WITH_CONTIKI) + union { + int fd; /**< on POSIX systems */ + void *conn; /**< opaque connection (e.g. uip_conn in Contiki) */ + } handle; /**< opaque handle to identify this endpoint */ +#endif /* WITH_POSIX or WITH_CONTIKI */ + +#ifdef WITH_LWIP + struct udp_pcb *pcb; + /**< @FIXME --chrysn + * this was added in a hurry, not sure it confirms to the overall model */ + struct coap_context_t *context; +#endif /* WITH_LWIP */ + + coap_address_t addr; /**< local interface address */ + int ifindex; + int flags; +} coap_endpoint_t; + +#define COAP_ENDPOINT_NOSEC 0x00 +#define COAP_ENDPOINT_DTLS 0x01 + +coap_endpoint_t *coap_new_endpoint(const coap_address_t *addr, int flags); + +void coap_free_endpoint(coap_endpoint_t *ep); + +/** + * Function interface for data transmission. This function returns the number of + * bytes that have been transmitted, or a value less than zero on error. + * + * @param context The calling CoAP context. + * @param local_interface The local interface to send the data. + * @param dst The address of the receiver. + * @param data The data to send. + * @param datalen The actual length of @p data. + * + * @return The number of bytes written on success, or a value + * less than zero on error. + */ +ssize_t coap_network_send(struct coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char *data, size_t datalen); + +/** + * Function interface for reading data. This function returns the number of + * bytes that have been read, or a value less than zero on error. In case of an + * error, @p *packet is set to NULL. + * + * @param ep The endpoint that is used for reading data from the network. + * @param packet A result parameter where a pointer to the received packet + * structure is stored. The caller must call coap_free_packet to + * release the storage used by this packet. + * + * @return The number of bytes received on success, or a value less than + * zero on error. + */ +ssize_t coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet); + +#ifndef coap_mcast_interface +# define coap_mcast_interface(Local) 0 +#endif + +/** + * Releases the storage allocated for @p packet. + */ +void coap_free_packet(coap_packet_t *packet); + +/** + * Populate the coap_endpoint_t *target from the incoming packet's destination + * data. + * + * This is usually used to copy a packet's data into a node's local_if member. + */ +void coap_packet_populate_endpoint(coap_packet_t *packet, + coap_endpoint_t *target); + +/** + * Given an incoming packet, copy its source address into an address struct. + */ +void coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target); + +/** + * Given a packet, set msg and msg_len to an address and length of the packet's + * data in memory. + * */ +void coap_packet_get_memmapped(coap_packet_t *packet, + unsigned char **address, + size_t *length); + +#ifdef WITH_LWIP +/** + * Get the pbuf of a packet. The caller takes over responsibility for freeing + * the pbuf. + */ +struct pbuf *coap_packet_extract_pbuf(coap_packet_t *packet); +#endif + +#ifdef WITH_CONTIKI +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in mem.c. + */ +struct coap_packet_t { + coap_if_handle_t hnd; /**< the interface handle */ + coap_address_t src; /**< the packet's source address */ + coap_address_t dst; /**< the packet's destination address */ + const coap_endpoint_t *interface; + int ifindex; + void *session; /**< opaque session data */ + size_t length; /**< length of payload */ + unsigned char payload[]; /**< payload */ +}; +#endif + +#ifdef WITH_LWIP +/* + * This is only included in coap_io.h instead of .c in order to be available for + * sizeof in lwippools.h. + * Simple carry-over of the incoming pbuf that is later turned into a node. + * + * Source address data is currently side-banded via ip_current_dest_addr & co + * as the packets have limited lifetime anyway. + */ +struct coap_packet_t { + struct pbuf *pbuf; + const coap_endpoint_t *local_interface; + uint16_t srcport; +}; +#endif + +#endif /* _COAP_IO_H_ */ diff --git a/tools/sdk/include/coap/coap/coap_time.h b/tools/sdk/include/coap/coap/coap_time.h new file mode 100644 index 00000000..9357e5ff --- /dev/null +++ b/tools/sdk/include/coap/coap/coap_time.h @@ -0,0 +1,142 @@ +/* + * coap_time.h -- Clock Handling + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file coap_time.h + * @brief Clock Handling + */ + +#ifndef _COAP_TIME_H_ +#define _COAP_TIME_H_ + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. + * @{ + */ + +#ifdef WITH_LWIP + +#include +#include + +/* lwIP provides ms in sys_now */ +#define COAP_TICKS_PER_SECOND 1000 + +typedef uint32_t coap_tick_t; +typedef uint32_t coap_time_t; +typedef int32_t coap_tick_diff_t; + +static inline void coap_ticks_impl(coap_tick_t *t) { + *t = sys_now(); +} + +static inline void coap_clock_init_impl(void) { +} + +#define coap_clock_init coap_clock_init_impl +#define coap_ticks coap_ticks_impl + +static inline coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} +#endif + +#ifdef WITH_CONTIKI +#include "clock.h" + +typedef clock_time_t coap_tick_t; +typedef clock_time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef int coap_tick_diff_t; + +#define COAP_TICKS_PER_SECOND CLOCK_SECOND + +static inline void coap_clock_init(void) { + clock_init(); +} + +static inline void coap_ticks(coap_tick_t *t) { + *t = clock_time(); +} + +static inline coap_time_t coap_ticks_to_rt(coap_tick_t t) { + return t / COAP_TICKS_PER_SECOND; +} +#endif /* WITH_CONTIKI */ + +#ifdef WITH_POSIX +/** + * This data type represents internal timer ticks with COAP_TICKS_PER_SECOND + * resolution. + */ +typedef unsigned long coap_tick_t; + +/** + * CoAP time in seconds since epoch. + */ +typedef time_t coap_time_t; + +/** + * This data type is used to represent the difference between two clock_tick_t + * values. This data type must have the same size in memory as coap_tick_t to + * allow wrapping. + */ +typedef long coap_tick_diff_t; + +/** Use ms resolution on POSIX systems */ +#define COAP_TICKS_PER_SECOND 1000 + +/** + * Initializes the internal clock. + */ +void coap_clock_init(void); + +/** + * Sets @p t to the internal time with COAP_TICKS_PER_SECOND resolution. + */ +void coap_ticks(coap_tick_t *t); + +/** + * Helper function that converts coap ticks to wallclock time. On POSIX, this + * function returns the number of seconds since the epoch. On other systems, it + * may be the calculated number of seconds since last reboot or so. + * + * @param t Internal system ticks. + * + * @return The number of seconds that has passed since a specific reference + * point (seconds since epoch on POSIX). + */ +coap_time_t coap_ticks_to_rt(coap_tick_t t); +#endif /* WITH_POSIX */ + +/** + * Returns @c 1 if and only if @p a is less than @p b where less is defined on a + * signed data type. + */ +static inline int coap_time_lt(coap_tick_t a, coap_tick_t b) { + return ((coap_tick_diff_t)(a - b)) < 0; +} + +/** + * Returns @c 1 if and only if @p a is less than or equal @p b where less is + * defined on a signed data type. + */ +static inline int coap_time_le(coap_tick_t a, coap_tick_t b) { + return a == b || coap_time_lt(a,b); +} + +/** @} */ + +#endif /* _COAP_TIME_H_ */ diff --git a/tools/sdk/include/coap/coap/debug.h b/tools/sdk/include/coap/coap/debug.h new file mode 100644 index 00000000..e7c86aff --- /dev/null +++ b/tools/sdk/include/coap/coap/debug.h @@ -0,0 +1,85 @@ +/* + * debug.h -- debug utilities + * + * Copyright (C) 2010-2011,2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_DEBUG_H_ +#define _COAP_DEBUG_H_ + +#ifndef COAP_DEBUG_FD +#define COAP_DEBUG_FD stdout +#endif + +#ifndef COAP_ERR_FD +#define COAP_ERR_FD stderr +#endif + +#ifdef HAVE_SYSLOG_H +#include +typedef short coap_log_t; +#else +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { + LOG_EMERG=0, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG +} coap_log_t; +#endif + +/** Returns the current log level. */ +coap_log_t coap_get_log_level(void); + +/** Sets the log level to the specified value. */ +void coap_set_log_level(coap_log_t level); + +/** Returns a zero-terminated string with the name of this library. */ +const char *coap_package_name(void); + +/** Returns a zero-terminated string with the library version. */ +const char *coap_package_version(void); + +/** + * Writes the given text to @c COAP_ERR_FD (for @p level <= @c LOG_CRIT) or @c + * COAP_DEBUG_FD (for @p level >= @c LOG_WARNING). The text is output only when + * @p level is below or equal to the log level that set by coap_set_log_level(). + */ +void coap_log_impl(coap_log_t level, const char *format, ...); + +#ifndef coap_log +#define coap_log(...) coap_log_impl(__VA_ARGS__) +#endif + +#ifndef NDEBUG + +/* A set of convenience macros for common log levels. */ +#define info(...) coap_log(LOG_INFO, __VA_ARGS__) +#define warn(...) coap_log(LOG_WARNING, __VA_ARGS__) +#define debug(...) coap_log(LOG_DEBUG, __VA_ARGS__) + +#include "pdu.h" +void coap_show_pdu(const coap_pdu_t *); + +struct coap_address_t; +size_t coap_print_addr(const struct coap_address_t *, unsigned char *, size_t); + +#else + +#define debug(...) +#define info(...) +#define warn(...) + +#define coap_show_pdu(x) +#define coap_print_addr(...) + +#endif /* NDEBUG */ + +#endif /* _COAP_DEBUG_H_ */ diff --git a/tools/sdk/include/coap/coap/encode.h b/tools/sdk/include/coap/coap/encode.h new file mode 100644 index 00000000..a5d290c4 --- /dev/null +++ b/tools/sdk/include/coap/coap/encode.h @@ -0,0 +1,52 @@ +/* + * encode.h -- encoding and decoding of CoAP data types + * + * Copyright (C) 2010-2012 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_ENCODE_H_ +#define _COAP_ENCODE_H_ + +#if (BSD >= 199103) || defined(WITH_CONTIKI) +# include +#else +# include +#endif + +#define Nn 8 /* duplicate definition of N if built on sky motes */ +#define ENCODE_HEADER_SIZE 4 +#define HIBIT (1 << (Nn - 1)) +#define EMASK ((1 << ENCODE_HEADER_SIZE) - 1) +#define MMASK ((1 << Nn) - 1 - EMASK) +#define MAX_VALUE ( (1 << Nn) - (1 << ENCODE_HEADER_SIZE) ) * (1 << ((1 << ENCODE_HEADER_SIZE) - 1)) + +#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK)) + +#ifndef HAVE_FLS +/* include this only if fls() is not available */ +extern int coap_fls(unsigned int i); +#else +#define coap_fls(i) fls(i) +#endif + +/* ls and s must be integer variables */ +#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls) +#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls)) + +/** + * Decodes multiple-length byte sequences. buf points to an input byte sequence + * of length len. Returns the decoded value. + */ +unsigned int coap_decode_var_bytes(unsigned char *buf,unsigned int len); + +/** + * Encodes multiple-length byte sequences. buf points to an output buffer of + * sufficient length to store the encoded bytes. val is the value to encode. + * Returns the number of bytes used to encode val or 0 on error. + */ +unsigned int coap_encode_var_bytes(unsigned char *buf, unsigned int val); + +#endif /* _COAP_ENCODE_H_ */ diff --git a/tools/sdk/include/coap/coap/hashkey.h b/tools/sdk/include/coap/coap/hashkey.h new file mode 100644 index 00000000..5cff67d2 --- /dev/null +++ b/tools/sdk/include/coap/coap/hashkey.h @@ -0,0 +1,57 @@ +/* + * hashkey.h -- definition of hash key type and helper functions + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file hashkey.h + * @brief definition of hash key type and helper functions + */ + +#ifndef _COAP_HASHKEY_H_ +#define _COAP_HASHKEY_H_ + +#include "str.h" + +typedef unsigned char coap_key_t[4]; + +#ifndef coap_hash +/** + * Calculates a fast hash over the given string @p s of length @p len and stores + * the result into @p h. Depending on the exact implementation, this function + * cannot be used as one-way function to check message integrity or simlar. + * + * @param s The string used for hash calculation. + * @param len The length of @p s. + * @param h The result buffer to store the calculated hash key. + */ +void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); + +#define coap_hash(String,Length,Result) \ + coap_hash_impl((String),(Length),(Result)) + +/* This is used to control the pre-set hash-keys for resources. */ +#define __COAP_DEFAULT_HASH +#else +#undef __COAP_DEFAULT_HASH +#endif /* coap_hash */ + +/** + * Calls coap_hash() with given @c str object as parameter. + * + * @param Str Must contain a pointer to a coap string object. + * @param H A coap_key_t object to store the result. + * + * @hideinitializer + */ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((Str)->s, (Str)->length, (H)); \ + } + +#endif /* _COAP_HASHKEY_H_ */ diff --git a/tools/sdk/include/coap/coap/libcoap.h b/tools/sdk/include/coap/coap/libcoap.h new file mode 100644 index 00000000..214b9e23 --- /dev/null +++ b/tools/sdk/include/coap/coap/libcoap.h @@ -0,0 +1,26 @@ +/* + * libcoap.h -- platform specific header file for CoAP stack + * + * Copyright (C) 2015 Carsten Schoenert + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _LIBCOAP_H_ +#define _LIBCOAP_H_ + +/* The non posix embedded platforms like Contiki, TinyOS, RIOT, ... doesn't have + * a POSIX compatible header structure so we have to slightly do some platform + * related things. Currently there is only Contiki available so we check for a + * CONTIKI environment and do *not* include the POSIX related network stuff. If + * there are other platforms in future there need to be analogous environments. + * + * The CONTIKI variable is within the Contiki build environment! */ + +#if !defined (CONTIKI) +#include +#include +#endif /* CONTIKI */ + +#endif /* _LIBCOAP_H_ */ diff --git a/tools/sdk/include/coap/coap/lwippools.h b/tools/sdk/include/coap/coap/lwippools.h new file mode 100644 index 00000000..0bfb3f52 --- /dev/null +++ b/tools/sdk/include/coap/coap/lwippools.h @@ -0,0 +1,57 @@ +/* + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** Memory pool definitions for the libcoap when used with lwIP (which has its + * own mechanism for quickly allocating chunks of data with known sizes). Has + * to be findable by lwIP (ie. an #include must either directly + * include this or include something more generic which includes this), and + * MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */ + +#include "coap_config.h" +#include +#include +#include + +#ifndef MEMP_NUM_COAPCONTEXT +#define MEMP_NUM_COAPCONTEXT 1 +#endif + +#ifndef MEMP_NUM_COAPENDPOINT +#define MEMP_NUM_COAPENDPOINT 1 +#endif + +/* 1 is sufficient as this is very short-lived */ +#ifndef MEMP_NUM_COAPPACKET +#define MEMP_NUM_COAPPACKET 1 +#endif + +#ifndef MEMP_NUM_COAPNODE +#define MEMP_NUM_COAPNODE 4 +#endif + +#ifndef MEMP_NUM_COAPPDU +#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE +#endif + +#ifndef MEMP_NUM_COAP_SUBSCRIPTION +#define MEMP_NUM_COAP_SUBSCRIPTION 4 +#endif + +#ifndef MEMP_NUM_COAPRESOURCE +#define MEMP_NUM_COAPRESOURCE 10 +#endif + +#ifndef MEMP_NUM_COAPRESOURCEATTR +#define MEMP_NUM_COAPRESOURCEATTR 20 +#endif + +LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") +LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") +LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") +LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") +LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") +LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") +LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") diff --git a/tools/sdk/include/coap/coap/mem.h b/tools/sdk/include/coap/coap/mem.h new file mode 100644 index 00000000..fd3c69aa --- /dev/null +++ b/tools/sdk/include/coap/coap/mem.h @@ -0,0 +1,111 @@ +/* + * mem.h -- CoAP memory handling + * + * Copyright (C) 2010-2011,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_MEM_H_ +#define _COAP_MEM_H_ + +#include + +#ifndef WITH_LWIP +/** + * Initializes libcoap's memory management. + * This function must be called once before coap_malloc() can be used on + * constrained devices. + */ +void coap_memory_init(void); +#endif /* WITH_LWIP */ + +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed to + * facilitate arrays of type objects to be used instead of dynamic memory + * management on constrained devices. + */ +typedef enum { + COAP_STRING, + COAP_ATTRIBUTE_NAME, + COAP_ATTRIBUTE_VALUE, + COAP_PACKET, + COAP_NODE, + COAP_CONTEXT, + COAP_ENDPOINT, + COAP_PDU, + COAP_PDU_BUF, + COAP_RESOURCE, + COAP_RESOURCEATTR +} coap_memory_tag_t; + +#ifndef WITH_LWIP + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the newly + * allocated memory. The @p type is used to select the appropriate storage + * container on constrained devices. The storage allocated by coap_malloc_type() + * must be released with coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). The type tag @p + * type must be the same that was used for allocating the object pointed to by + * @p . + * + * @param type The type of the object to release. + * @param p A pointer to memory that was allocated by coap_malloc_type(). + */ +void coap_free_type(coap_memory_tag_t type, void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +static inline void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +static inline void coap_free(void *object) { + coap_free_type(COAP_STRING, object); +} + +#endif /* not WITH_LWIP */ + +#ifdef WITH_LWIP + +#include + +/* no initialization needed with lwip (or, more precisely: lwip must be + * completely initialized anyway by the time coap gets active) */ +static inline void coap_memory_init(void) {} + +/* It would be nice to check that size equals the size given at the memp + * declaration, but i currently don't see a standard way to check that without + * sourcing the custom memp pools and becoming dependent of its syntax + */ +#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_free_type(type, p) memp_free(MEMP_ ## type, p) + +/* Those are just here to make uri.c happy where string allocation has not been + * made conditional. + */ +static inline void *coap_malloc(size_t size) { + LWIP_ASSERT("coap_malloc must not be used in lwIP", 0); +} + +static inline void coap_free(void *pointer) { + LWIP_ASSERT("coap_free must not be used in lwIP", 0); +} + +#endif /* WITH_LWIP */ + +#endif /* _COAP_MEM_H_ */ diff --git a/tools/sdk/include/coap/coap/net.h b/tools/sdk/include/coap/coap/net.h new file mode 100644 index 00000000..014b4903 --- /dev/null +++ b/tools/sdk/include/coap/coap/net.h @@ -0,0 +1,521 @@ +/* + * net.h -- CoAP network interface + * + * Copyright (C) 2010-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_NET_H_ +#define _COAP_NET_H_ + +#include +#include +#include +#include +#include + +#ifdef WITH_LWIP +#include +#endif + +#include "coap_io.h" +#include "coap_time.h" +#include "option.h" +#include "pdu.h" +#include "prng.h" + +struct coap_queue_t; + +typedef struct coap_queue_t { + struct coap_queue_t *next; + coap_tick_t t; /**< when to send PDU for the next time */ + unsigned char retransmit_cnt; /**< retransmission counter, will be removed + * when zero */ + unsigned int timeout; /**< the randomized timeout value */ + coap_endpoint_t local_if; /**< the local address interface */ + coap_address_t remote; /**< remote address */ + coap_tid_t id; /**< unique transaction id */ + coap_pdu_t *pdu; /**< the CoAP PDU to send */ +} coap_queue_t; + +/** Adds node to given queue, ordered by node->t. */ +int coap_insert_node(coap_queue_t **queue, coap_queue_t *node); + +/** Destroys specified node. */ +int coap_delete_node(coap_queue_t *node); + +/** Removes all items from given queue and frees the allocated storage. */ +void coap_delete_all(coap_queue_t *queue); + +/** Creates a new node suitable for adding to the CoAP sendqueue. */ +coap_queue_t *coap_new_node(void); + +struct coap_resource_t; +struct coap_context_t; +#ifndef WITHOUT_ASYNC +struct coap_async_state_t; +#endif + +/** Message handler that is used as call-back in coap_context_t */ +typedef void (*coap_response_handler_t)(struct coap_context_t *, + const coap_endpoint_t *local_interface, + const coap_address_t *remote, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id); + +#define COAP_MID_CACHE_SIZE 3 +typedef struct { + unsigned char flags[COAP_MID_CACHE_SIZE]; + coap_key_t item[COAP_MID_CACHE_SIZE]; +} coap_mid_cache_t; + +/** The CoAP stack's global state is stored in a coap_context_t object */ +typedef struct coap_context_t { + coap_opt_filter_t known_options; + struct coap_resource_t *resources; /**< hash table or list of known resources */ + +#ifndef WITHOUT_ASYNC + /** + * list of asynchronous transactions */ + struct coap_async_state_t *async_state; +#endif /* WITHOUT_ASYNC */ + + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue; + coap_endpoint_t *endpoint; /**< the endpoint used for listening */ + +#ifdef WITH_POSIX + int sockfd; /**< send/receive socket */ +#endif /* WITH_POSIX */ + +#ifdef WITH_CONTIKI + struct uip_udp_conn *conn; /**< uIP connection object */ + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ + struct etimer notify_timer; /**< used to check resources periodically */ +#endif /* WITH_CONTIKI */ + +#ifdef WITH_LWIP + uint8_t timer_configured; /**< Set to 1 when a retransmission is + * scheduled using lwIP timers for this + * context, otherwise 0. */ +#endif /* WITH_LWIP */ + + /** + * The last message id that was used is stored in this field. The initial + * value is set by coap_new_context() and is usually a random value. A new + * message id can be created with coap_new_message_id(). + */ + unsigned short message_id; + + /** + * The next value to be used for Observe. This field is global for all + * resources and will be updated when notifications are created. + */ + unsigned int observe; + + coap_response_handler_t response_handler; + + ssize_t (*network_send)(struct coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char *data, size_t datalen); + + ssize_t (*network_read)(coap_endpoint_t *ep, coap_packet_t **packet); + +} coap_context_t; + +/** + * Registers a new message handler that is called whenever a response was + * received that matches an ongoing transaction. + * + * @param context The context to register the handler for. + * @param handler The response handler to register. + */ +static inline void +coap_register_response_handler(coap_context_t *context, + coap_response_handler_t handler) { + context->response_handler = handler; +} + +/** + * Registers the option type @p type with the given context object @p ctx. + * + * @param ctx The context to use. + * @param type The option type to register. + */ +inline static void +coap_register_option(coap_context_t *ctx, unsigned char type) { + coap_option_setb(ctx->known_options, type); +} + +/** + * Set sendqueue_basetime in the given context object @p ctx to @p now. This + * function returns the number of elements in the queue head that have timed + * out. + */ +unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now); + +/** + * Returns the next pdu to send without removing from sendqeue. + */ +coap_queue_t *coap_peek_next( coap_context_t *context ); + +/** + * Returns the next pdu to send and removes it from the sendqeue. + */ +coap_queue_t *coap_pop_next( coap_context_t *context ); + +/** + * Creates a new coap_context_t object that will hold the CoAP stack status. + */ +coap_context_t *coap_new_context(const coap_address_t *listen_addr); + +/** + * Returns a new message id and updates @p context->message_id accordingly. The + * message id is returned in network byte order to make it easier to read in + * tracing tools. + * + * @param context The current coap_context_t object. + * + * @return Incremented message id in network byte order. + */ +static inline unsigned short +coap_new_message_id(coap_context_t *context) { + context->message_id++; +#ifndef WITH_CONTIKI + return htons(context->message_id); +#else /* WITH_CONTIKI */ + return uip_htons(context->message_id); +#endif +} + +/** + * CoAP stack context must be released with coap_free_context(). This function + * clears all entries from the receive queue and send queue and deletes the + * resources that have been registered with @p context, and frees the attached + * endpoints. + */ +void coap_free_context(coap_context_t *context); + + +/** + * Sends a confirmed CoAP message to given destination. The memory that is + * allocated by pdu will not be released by coap_send_confirmed(). The caller + * must release the memory. + * + * @param context The CoAP context to use. + * @param local_interface The local network interface where the outbound + * packet is sent. + * @param dst The address to send to. + * @param pdu The CoAP PDU to send. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_confirmed(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *pdu); + +/** + * Creates a new ACK PDU with specified error @p code. The options specified by + * the filter expression @p opts will be copied from the original request + * contained in @p request. Unless @c SHORT_ERROR_RESPONSE was defined at build + * time, the textual reason phrase for @p code will be added as payload, with + * Content-Type @c 0. + * This function returns a pointer to the new response message, or @c NULL on + * error. The storage allocated for the new message must be relased with + * coap_free(). + * + * @param request Specification of the received (confirmable) request. + * @param code The error code to set. + * @param opts An option filter that specifies which options to copy from + * the original request in @p node. + * + * @return A pointer to the new message or @c NULL on error. + */ +coap_pdu_t *coap_new_error_response(coap_pdu_t *request, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Sends a non-confirmed CoAP message to given destination. The memory that is + * allocated by pdu will not be released by coap_send(). + * The caller must release the memory. + * + * @param context The CoAP context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The address to send to. + * @param pdu The CoAP PDU to send. + * + * @return The message id of the sent message or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *pdu); + +/** + * Sends an error response with code @p code for request @p request to @p dst. + * @p opts will be passed to coap_new_error_response() to copy marked options + * from the request. This function returns the transaction id if the message was + * sent, or @c COAP_INVALID_TID otherwise. + * + * @param context The context to use. + * @param request The original request to respond to. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The remote peer that sent the request. + * @param code The response code. + * @param opts A filter that specifies the options to copy from the + * @p request. + * + * @return The transaction id if the message was sent, or @c + * COAP_INVALID_TID otherwise. + */ +coap_tid_t coap_send_error(coap_context_t *context, + coap_pdu_t *request, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char code, + coap_opt_filter_t opts); + +/** + * Helper funktion to create and send a message with @p type (usually ACK or + * RST). This function returns @c COAP_INVALID_TID when the message was not + * sent, a valid transaction id otherwise. + * + * @param context The CoAP context. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst Where to send the context. + * @param request The request that should be responded to. + * @param type Which type to set. + * @return transaction id on success or @c COAP_INVALID_TID + * otherwise. + */ +coap_tid_t +coap_send_message_type(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request, + unsigned char type); + +/** + * Sends an ACK message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param context The context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The destination address. + * @param request The request to be acknowledged. + * + * @return The transaction id if ACK was sent or @c + * COAP_INVALID_TID on error. + */ +coap_tid_t coap_send_ack(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request); + +/** + * Sends an RST message with code @c 0 for the specified @p request to @p dst. + * This function returns the corresponding transaction id if the message was + * sent or @c COAP_INVALID_TID on error. + * + * @param context The context to use. + * @param local_interface The local network interface where the outbound packet + * is sent. + * @param dst The destination address. + * @param request The request to be reset. + * + * @return The transaction id if RST was sent or @c + * COAP_INVALID_TID on error. + */ +static inline coap_tid_t +coap_send_rst(coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + coap_pdu_t *request) { + return coap_send_message_type(context, + local_interface, + dst, request, + COAP_MESSAGE_RST); +} + +/** + * Handles retransmissions of confirmable messages + */ +coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node); + +/** + * Reads data from the network and tries to parse as CoAP PDU. On success, 0 is + * returned and a new node with the parsed PDU is added to the receive queue in + * the specified context object. + */ +int coap_read(coap_context_t *context); + +/** + * Parses and interprets a CoAP message with context @p ctx. This function + * returns @c 0 if the message was handled, or a value less than zero on + * error. + * + * @param ctx The current CoAP context. + * @param packet The received packet. + * + * @return @c 0 if message was handled successfully, or less than zero on + * error. + */ +int coap_handle_message(coap_context_t *ctx, + coap_packet_t *packet); + +/** + * Calculates a unique transaction id from given arguments @p peer and @p pdu. + * The id is returned in @p id. + * + * @param peer The remote party who sent @p pdu. + * @param pdu The message that initiated the transaction. + * @param id Set to the new id. + */ +void coap_transaction_id(const coap_address_t *peer, + const coap_pdu_t *pdu, + coap_tid_t *id); + +/** + * This function removes the element with given @p id from the list given list. + * If @p id was found, @p node is updated to point to the removed element. Note + * that the storage allocated by @p node is @b not released. The caller must do + * this manually using coap_delete_node(). This function returns @c 1 if the + * element with id @p id was found, @c 0 otherwise. For a return value of @c 0, + * the contents of @p node is undefined. + * + * @param queue The queue to search for @p id. + * @param id The node id to look for. + * @param node If found, @p node is updated to point to the removed node. You + * must release the storage pointed to by @p node manually. + * + * @return @c 1 if @p id was found, @c 0 otherwise. + */ +int coap_remove_from_queue(coap_queue_t **queue, + coap_tid_t id, + coap_queue_t **node); + +/** + * Removes the transaction identified by @p id from given @p queue. This is a + * convenience function for coap_remove_from_queue() with automatic deletion of + * the removed node. + * + * @param queue The queue to search for @p id. + * @param id The transaction id. + * + * @return @c 1 if node was found, removed and destroyed, @c 0 otherwise. + */ +inline static int +coap_remove_transaction(coap_queue_t **queue, coap_tid_t id) { + coap_queue_t *node; + if (!coap_remove_from_queue(queue, id, &node)) + return 0; + + coap_delete_node(node); + return 1; +} + +/** + * Retrieves transaction from the queue. + * + * @param queue The transaction queue to be searched. + * @param id Unique key of the transaction to find. + * + * @return A pointer to the transaction object or NULL if not found. + */ +coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_tid_t id); + +/** + * Cancels all outstanding messages for peer @p dst that have the specified + * token. + * + * @param context The context in use. + * @param dst Destination address of the messages to remove. + * @param token Message token. + * @param token_length Actual length of @p token. + */ +void coap_cancel_all_messages(coap_context_t *context, + const coap_address_t *dst, + const unsigned char *token, + size_t token_length); + +/** + * Dispatches the PDUs from the receive queue in given context. + */ +void coap_dispatch(coap_context_t *context, coap_queue_t *rcvd); + +/** + * Returns 1 if there are no messages to send or to dispatch in the context's + * queues. */ +int coap_can_exit(coap_context_t *context); + +/** + * Returns the current value of an internal tick counter. The counter counts \c + * COAP_TICKS_PER_SECOND ticks every second. + */ +void coap_ticks(coap_tick_t *); + +/** + * Verifies that @p pdu contains no unknown critical options. Options must be + * registered at @p ctx, using the function coap_register_option(). A basic set + * of options is registered automatically by coap_new_context(). This function + * returns @c 1 if @p pdu is ok, @c 0 otherwise. The given filter object @p + * unknown will be updated with the unknown options. As only @c COAP_MAX_OPT + * options can be signalled this way, remaining options must be examined + * manually. + * + * @code + coap_opt_filter_t f = COAP_OPT_NONE; + coap_opt_iterator_t opt_iter; + + if (coap_option_check_critical(ctx, pdu, f) == 0) { + coap_option_iterator_init(pdu, &opt_iter, f); + + while (coap_option_next(&opt_iter)) { + if (opt_iter.type & 0x01) { + ... handle unknown critical option in opt_iter ... + } + } + } + * @endcode + * + * @param ctx The context where all known options are registered. + * @param pdu The PDU to check. + * @param unknown The output filter that will be updated to indicate the + * unknown critical options found in @p pdu. + * + * @return @c 1 if everything was ok, @c 0 otherwise. + */ +int coap_option_check_critical(coap_context_t *ctx, + coap_pdu_t *pdu, + coap_opt_filter_t unknown); + +/** + * Creates a new response for given @p request with the contents of @c + * .well-known/core. The result is NULL on error or a newly allocated PDU that + * must be released by coap_delete_pdu(). + * + * @param context The current coap context to use. + * @param request The request for @c .well-known/core . + * + * @return A new 2.05 response for @c .well-known/core or NULL on error. + */ +coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_pdu_t *request); + +#endif /* _COAP_NET_H_ */ diff --git a/tools/sdk/include/coap/coap/option.h b/tools/sdk/include/coap/coap/option.h new file mode 100644 index 00000000..ace2b81c --- /dev/null +++ b/tools/sdk/include/coap/coap/option.h @@ -0,0 +1,410 @@ +/* + * option.h -- helpers for handling options in CoAP PDUs + * + * Copyright (C) 2010-2013 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file option.h + * @brief Helpers for handling options in CoAP PDUs + */ + +#ifndef _COAP_OPTION_H_ +#define _COAP_OPTION_H_ + +#include "bits.h" +#include "pdu.h" + +/** + * Use byte-oriented access methods here because sliding a complex struct + * coap_opt_t over the data buffer may cause bus error on certain platforms. + */ +typedef unsigned char coap_opt_t; +#define PCHAR(p) ((coap_opt_t *)(p)) + +/** Representation of CoAP options. */ +typedef struct { + unsigned short delta; + size_t length; + unsigned char *value; +} coap_option_t; + +/** + * Parses the option pointed to by @p opt into @p result. This function returns + * the number of bytes that have been parsed, or @c 0 on error. An error is + * signaled when illegal delta or length values are encountered or when option + * parsing would result in reading past the option (i.e. beyond opt + length). + * + * @param opt The beginning of the option to parse. + * @param length The maximum length of @p opt. + * @param result A pointer to the coap_option_t structure that is filled with + * actual values iff coap_opt_parse() > 0. + * @return The number of bytes parsed or @c 0 on error. + */ +size_t coap_opt_parse(const coap_opt_t *opt, + size_t length, + coap_option_t *result); + +/** + * Returns the size of the given option, taking into account a possible option + * jump. + * + * @param opt An option jump or the beginning of the option. + * @return The number of bytes between @p opt and the end of the option + * starting at @p opt. In case of an error, this function returns + * @c 0 as options need at least one byte storage space. + */ +size_t coap_opt_size(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_size() instead. } */ +#define COAP_OPT_SIZE(opt) coap_opt_size(opt) + +/** + * Calculates the beginning of the PDU's option section. + * + * @param pdu The PDU containing the options. + * @return A pointer to the first option if available, or @c NULL otherwise. + */ +coap_opt_t *options_start(coap_pdu_t *pdu); + +/** + * Interprets @p opt as pointer to a CoAP option and advances to + * the next byte past this option. + * @hideinitializer + */ +#define options_next(opt) \ + ((coap_opt_t *)((unsigned char *)(opt) + COAP_OPT_SIZE(opt))) + +/** + * @defgroup opt_filter Option Filters + * @{ + */ + +/** + * The number of option types below 256 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_SHORT 6 + +/** + * The number of option types above 255 that can be stored in an + * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be + * at most 16. Each coap_option_filter_t object reserves + * COAP_OPT_FILTER_LONG * 2 bytes for short options. + */ +#define COAP_OPT_FILTER_LONG 2 + +/* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set + * correctly. */ +#if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) +#error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16 +#endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */ + +/** The number of elements in coap_opt_filter_t. */ +#define COAP_OPT_FILTER_SIZE \ + (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1 + +/** + * Fixed-size vector we use for option filtering. It is large enough + * to hold COAP_OPT_FILTER_SHORT entries with an option number between + * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number + * between 256 and 65535. Its internal structure is + * + * @code +struct { + uint16_t mask; + uint16_t long_opts[COAP_OPT_FILTER_LONG]; + uint8_t short_opts[COAP_OPT_FILTER_SHORT]; +} + * @endcode + * + * The first element contains a bit vector that indicates which fields + * in the remaining array are used. The first COAP_OPT_FILTER_LONG + * bits correspond to the long option types that are stored in the + * elements from index 1 to COAP_OPT_FILTER_LONG. The next + * COAP_OPT_FILTER_SHORT bits correspond to the short option types + * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1 + * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter + * elements are treated as bytes. + */ +typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE]; + +/** Pre-defined filter that includes all options. */ +#define COAP_OPT_ALL NULL + +/** + * Clears filter @p f. + * + * @param f The filter to clear. + */ +static inline void +coap_option_filter_clear(coap_opt_filter_t f) { + memset(f, 0, sizeof(coap_opt_filter_t)); +} + +/** + * Sets the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_set(coap_opt_filter_t filter, unsigned short type); + +/** + * Clears the corresponding entry for @p type in @p filter. This + * function returns @c 1 if bit was set or @c 0 on error (i.e. when + * the given type does not fit in the filter). + * + * @param filter The filter object to change. + * @param type The type that should be cleared from the filter. + * + * @return @c 1 if bit was set, @c 0 otherwise. + */ +int coap_option_filter_unset(coap_opt_filter_t filter, unsigned short type); + +/** + * Checks if @p type is contained in @p filter. This function returns + * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given + * type does not fit in the filter). + * + * @param filter The filter object to search. + * @param type The type to search for. + * + * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error. + */ +int coap_option_filter_get(const coap_opt_filter_t filter, unsigned short type); + +/** + * Sets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in + * the filter). + * + * @deprecated Use coap_option_filter_set() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be set. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +inline static int +coap_option_setb(coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_set(filter, type) ? 1 : -1; +} + +/** + * Clears the corresponding bit for @p type in @p filter. This function returns + * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not + * fit in the filter). + * + * @deprecated Use coap_option_filter_unset() instead. + * + * @param filter The filter object to change. + * @param type The type for which the bit should be cleared. + * + * @return @c 1 if bit was set, @c -1 otherwise. + */ +inline static int +coap_option_clrb(coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_unset(filter, type) ? 1 : -1; +} + +/** + * Gets the corresponding bit for @p type in @p filter. This function returns @c + * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type + * does not fit in the filter). + * + * @deprecated Use coap_option_filter_get() instead. + * + * @param filter The filter object to read bit from. + * @param type The type for which the bit should be read. + * + * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. + */ +inline static int +coap_option_getb(const coap_opt_filter_t filter, unsigned short type) { + return coap_option_filter_get(filter, type); +} + +/** + * Iterator to run through PDU options. This object must be + * initialized with coap_option_iterator_init(). Call + * coap_option_next() to walk through the list of options until + * coap_option_next() returns @c NULL. + * + * @code + * coap_opt_t *option; + * coap_opt_iterator_t opt_iter; + * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + * + * while ((option = coap_option_next(&opt_iter))) { + * ... do something with option ... + * } + * @endcode + */ +typedef struct { + size_t length; /**< remaining length of PDU */ + unsigned short type; /**< decoded option type */ + unsigned int bad:1; /**< iterator object is ok if not set */ + unsigned int filtered:1; /**< denotes whether or not filter is used */ + coap_opt_t *next_option; /**< pointer to the unparsed next option */ + coap_opt_filter_t filter; /**< option filter */ +} coap_opt_iterator_t; + +/** + * Initializes the given option iterator @p oi to point to the beginning of the + * @p pdu's option list. This function returns @p oi on success, @c NULL + * otherwise (i.e. when no options exist). Note that a length check on the + * option list must be performed before coap_option_iterator_init() is called. + * + * @param pdu The PDU the options of which should be walked through. + * @param oi An iterator object that will be initilized. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. + * Fence-post options @c 14, @c 28, @c 42, ... are always + * skipped. + * + * @return The iterator object @p oi on success, @c NULL otherwise. + */ +coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, + coap_opt_iterator_t *oi, + const coap_opt_filter_t filter); + +/** + * Updates the iterator @p oi to point to the next option. This function returns + * a pointer to that option or @c NULL if no more options exist. The contents of + * @p oi will be updated. In particular, @c oi->n specifies the current option's + * ordinal number (counted from @c 1), @c oi->type is the option's type code, + * and @c oi->option points to the beginning of the current option itself. When + * advanced past the last option, @c oi->option will be @c NULL. + * + * Note that options are skipped whose corresponding bits in the filter + * specified with coap_option_iterator_init() are @c 0. Options with type codes + * that do not fit in this filter hence will always be returned. + * + * @param oi The option iterator to update. + * + * @return The next option or @c NULL if no more options exist. + */ +coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); + +/** + * Retrieves the first option of type @p type from @p pdu. @p oi must point to a + * coap_opt_iterator_t object that will be initialized by this function to + * filter only options with code @p type. This function returns the first option + * with this type, or @c NULL if not found. + * + * @param pdu The PDU to parse for options. + * @param type The option type code to search for. + * @param oi An iterator object to use. + * + * @return A pointer to the first option of type @p type, or @c NULL if + * not found. + */ +coap_opt_t *coap_check_option(coap_pdu_t *pdu, + unsigned short type, + coap_opt_iterator_t *oi); + +/** + * Encodes the given delta and length values into @p opt. This function returns + * the number of bytes that were required to encode @p delta and @p length or @c + * 0 on error. Note that the result indicates by how many bytes @p opt must be + * advanced to encode the option value. + * + * @param opt The option buffer space where @p delta and @p length are + * written. + * @param maxlen The maximum length of @p opt. + * @param delta The actual delta value to encode. + * @param length The actual length value to encode. + * + * @return The number of bytes used or @c 0 on error. + */ +size_t coap_opt_setheader(coap_opt_t *opt, + size_t maxlen, + unsigned short delta, + size_t length); + +/** + * Encodes option with given @p delta into @p opt. This function returns the + * number of bytes written to @p opt or @c 0 on error. This happens especially + * when @p opt does not provide sufficient space to store the option value, + * delta, and option jumps when required. + * + * @param opt The option buffer space where @p val is written. + * @param n Maximum length of @p opt. + * @param delta The option delta. + * @param val The option value to copy into @p opt. + * @param length The actual length of @p val. + * + * @return The number of bytes that have been written to @p opt or @c 0 on + * error. The return value will always be less than @p n. + */ +size_t coap_opt_encode(coap_opt_t *opt, + size_t n, + unsigned short delta, + const unsigned char *val, + size_t length); + +/** + * Decodes the delta value of the next option. This function returns the number + * of bytes read or @c 0 on error. The caller of this function must ensure that + * it does not read over the boundaries of @p opt (e.g. by calling + * coap_opt_check_delta(). + * + * @param opt The option to examine. + * + * @return The number of bytes read or @c 0 on error. + */ +unsigned short coap_opt_delta(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_delta() instead. } */ +#define COAP_OPT_DELTA(opt) coap_opt_delta(opt) + +/** @deprecated { Use coap_opt_encode() instead. } */ +#define COAP_OPT_SETDELTA(opt,val) \ + coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0) + +/** + * Returns the length of the given option. @p opt must point to an option jump + * or the beginning of the option. This function returns @c 0 when @p opt is not + * an option or the actual length of @p opt (which can be @c 0 as well). + * + * @note {The rationale for using @c 0 in case of an error is that in most + * contexts, the result of this function is used to skip the next + * coap_opt_length() bytes.} + * + * @param opt The option whose length should be returned. + * + * @return The option's length or @c 0 when undefined. + */ +unsigned short coap_opt_length(const coap_opt_t *opt); + +/** @deprecated { Use coap_opt_length() instead. } */ +#define COAP_OPT_LENGTH(opt) coap_opt_length(opt) + +/** + * Returns a pointer to the value of the given option. @p opt must point to an + * option jump or the beginning of the option. This function returns @c NULL if + * @p opt is not a valid option. + * + * @param opt The option whose value should be returned. + * + * @return A pointer to the option value or @c NULL on error. + */ +unsigned char *coap_opt_value(coap_opt_t *opt); + +/** @deprecated { Use coap_opt_value() instead. } */ +#define COAP_OPT_VALUE(opt) coap_opt_value((coap_opt_t *)opt) + +/** @} */ + +#endif /* _OPTION_H_ */ diff --git a/tools/sdk/include/coap/coap/pdu.h b/tools/sdk/include/coap/coap/pdu.h new file mode 100644 index 00000000..7ed482de --- /dev/null +++ b/tools/sdk/include/coap/coap/pdu.h @@ -0,0 +1,388 @@ +/* + * pdu.h -- CoAP message structure + * + * Copyright (C) 2010-2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file pdu.h + * @brief Pre-defined constants that reflect defaults for CoAP + */ + +#ifndef _COAP_PDU_H_ +#define _COAP_PDU_H_ + +#include "uri.h" + +#ifdef WITH_LWIP +#include +#endif + +#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */ +#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ +#ifndef COAP_MAX_PDU_SIZE +#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU */ +#endif /* COAP_MAX_PDU_SIZE */ + +#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ +#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ + +/** well-known resources URI */ +#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" + +#ifdef __COAP_DEFAULT_HASH +/* pre-calculated hash key for the default well-known URI */ +#define COAP_DEFAULT_WKC_HASHKEY "\345\130\144\245" +#endif + +/* CoAP message types */ + +#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */ +#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */ +#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */ +#define COAP_MESSAGE_RST 3 /* indicates error in received messages */ + +/* CoAP request methods */ + +#define COAP_REQUEST_GET 1 +#define COAP_REQUEST_POST 2 +#define COAP_REQUEST_PUT 3 +#define COAP_REQUEST_DELETE 4 + +/* CoAP option types (be sure to update check_critical when adding options */ + +#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */ +#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */ +#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */ +#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */ +#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */ +#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */ +#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */ +#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */ +#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */ +#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */ +#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */ +#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */ +#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */ +#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */ + +/* option types from RFC 7641 */ + +#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */ +#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE + +/* selected option types from RFC 7959 */ + +#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */ +#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */ + +/* selected option types from RFC 7967 */ + +#define COAP_OPTION_NORESPONSE 258 /* N, uint, 0--1 B, 0 */ + +#define COAP_MAX_OPT 65535 /**< the highest option number we know */ + +/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */ + +/* As of draft-ietf-core-coap-04, response codes are encoded to base + * 32, i.e. the three upper bits determine the response class while + * the remaining five fine-grained information specific to that class. + */ +#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100) + +/* Determines the class of response code C */ +#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) + +#ifndef SHORT_ERROR_RESPONSE +/** + * Returns a human-readable response phrase for the specified CoAP response @p + * code. This function returns @c NULL if not found. + * + * @param code The response code for which the literal phrase should be + * retrieved. + * + * @return A zero-terminated string describing the error, or @c NULL if not + * found. + */ +char *coap_response_phrase(unsigned char code); + +#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */ + +#else +#define coap_response_phrase(x) ((char *)NULL) + +#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */ +#endif /* SHORT_ERROR_RESPONSE */ + +/* The following definitions exist for backwards compatibility */ +#if 0 /* this does not exist any more */ +#define COAP_RESPONSE_100 40 /* 100 Continue */ +#endif +#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */ +#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */ +#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */ +#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */ +#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */ +#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */ +#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */ +#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */ +#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */ +#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */ +#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */ +#if 0 /* these response codes do not have a valid code any more */ +# define COAP_RESPONSE_X_240 240 /* Token Option required by server */ +# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */ +#endif +#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */ + +/* CoAP media type encoding */ + +#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */ +#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */ +#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */ +#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */ +#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */ +#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */ +#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */ +#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */ + +/* Note that identifiers for registered media types are in the range 0-65535. We + * use an unallocated type here and hope for the best. */ +#define COAP_MEDIATYPE_ANY 0xff /* any media type */ + +/** + * coap_tid_t is used to store CoAP transaction id, i.e. a hash value + * built from the remote transport address and the message id of a + * CoAP PDU. Valid transaction ids are greater or equal zero. + */ +typedef int coap_tid_t; + +/** Indicates an invalid transaction id. */ +#define COAP_INVALID_TID -1 + +/** + * Indicates that a response is suppressed. This will occur for error + * responses if the request was received via IP multicast. + */ +#define COAP_DROPPED_RESPONSE -2 + +#ifdef WORDS_BIGENDIAN +typedef struct { + unsigned int version:2; /* protocol version */ + unsigned int type:2; /* type flag */ + unsigned int token_length:4; /* length of Token */ + unsigned int code:8; /* request method (value 1--10) or response + code (value 40-255) */ + unsigned short id; /* message id */ + unsigned char token[]; /* the actual token, if any */ +} coap_hdr_t; +#else +typedef struct { + unsigned int token_length:4; /* length of Token */ + unsigned int type:2; /* type flag */ + unsigned int version:2; /* protocol version */ + unsigned int code:8; /* request method (value 1--10) or response + code (value 40-255) */ + unsigned short id; /* transaction id (network byte order!) */ + unsigned char token[]; /* the actual token, if any */ +} coap_hdr_t; +#endif + +#define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG)->code == 0) +#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ + && ((MSG)->code < 32)) +#define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG)->code >= 64) + +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list + * in a CoAP message is limited by 0b11110000 + * marker */ + +#define COAP_OPT_END 0xF0 /* end marker */ + +#define COAP_PAYLOAD_START 0xFF /* payload marker */ + +/** + * Structures for more convenient handling of options. (To be used with ordered + * coap_list_t.) The option's data will be added to the end of the coap_option + * structure (see macro COAP_OPTION_DATA). + */ +typedef struct { + unsigned short key; /* the option key (no delta coding) */ + unsigned int length; +} coap_option; + +#define COAP_OPTION_KEY(option) (option).key +#define COAP_OPTION_LENGTH(option) (option).length +#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option)) + +/** + * Header structure for CoAP PDUs + */ + +typedef struct { + size_t max_size; /**< allocated storage for options and data */ + coap_hdr_t *hdr; /**< Address of the first byte of the CoAP message. + * This may or may not equal (coap_hdr_t*)(pdu+1) + * depending on the memory management + * implementation. */ + unsigned short max_delta; /**< highest option number */ + unsigned short length; /**< PDU length (including header, options, data) */ + unsigned char *data; /**< payload */ + +#ifdef WITH_LWIP + struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside + * inside the pbuf's payload, but this pointer + * has to be kept because no exact offset can be + * given. This field must not be accessed from + * outside, because the pbuf's reference count + * is checked to be 1 when the pbuf is assigned + * to the pdu, and the pbuf stays exclusive to + * this pdu. */ +#endif +} coap_pdu_t; + +/** + * Options in coap_pdu_t are accessed with the macro COAP_OPTION. + */ +#define COAP_OPTION(node) ((coap_option *)(node)->options) + +#ifdef WITH_LWIP +/** + * Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this + * function. + * + * The pbuf is checked for being contiguous, and for having only one reference. + * The reference is stored in the PDU and will be freed when the PDU is freed. + * + * (For now, these are fatal errors; in future, a new pbuf might be allocated, + * the data copied and the passed pbuf freed). + * + * This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards + * copying the contents of the pbuf to the pdu. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); +#endif + +/** + * Creates a new CoAP PDU of given @p size (must be large enough to hold the + * basic CoAP message header (coap_hdr_t). The function returns a pointer to the + * node coap_pdu_t object on success, or @c NULL on error. The storage allocated + * for the result must be released with coap_delete_pdu(). + * + * @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON, + * COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * @param code The message code. + * @param id The message id to set or COAP_INVALID_TID if unknown. + * @param size The number of bytes to allocate for the actual message. + * + * @return A pointer to the new PDU object or @c NULL on error. + */ +coap_pdu_t * +coap_pdu_init(unsigned char type, + unsigned char code, + unsigned short id, + size_t size); + +/** + * Clears any contents from @p pdu and resets @c version field, @c + * length and @c data pointers. @c max_size is set to @p size, any + * other field is set to @c 0. Note that @p pdu must be a valid + * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). + */ +void coap_pdu_clear(coap_pdu_t *pdu, size_t size); + +/** + * Creates a new CoAP PDU. + * The object is created on the heap and must be released using + * coap_delete_pdu(); + * + * @deprecated This function allocates the maximum storage for each + * PDU. Use coap_pdu_init() instead. + */ +coap_pdu_t *coap_new_pdu(void); + +void coap_delete_pdu(coap_pdu_t *); + +/** + * Parses @p data into the CoAP PDU structure given in @p result. + * This function returns @c 0 on error or a number greater than zero on success. + * + * @param data The raw data to parse as CoAP PDU. + * @param length The actual size of @p data. + * @param result The PDU structure to fill. Note that the structure must + * provide space for at least @p length bytes to hold the + * entire CoAP PDU. + * + * @return A value greater than zero on success or @c 0 on error. + */ +int coap_pdu_parse(unsigned char *data, + size_t length, + coap_pdu_t *result); + +/** + * Adds token of length @p len to @p pdu. + * Adding the token destroys any following contents of the pdu. Hence options + * and data must be added after coap_add_token() has been called. In @p pdu, + * length is set to @p len + @c 4, and max_delta is set to @c 0. This funtion + * returns @c 0 on error or a value greater than zero on success. + * + * @param pdu The PDU where the token is to be added. + * @param len The length of the new token. + * @param data The token to add. + * + * @return A value greater than zero on success, or @c 0 on error. + */ +int coap_add_token(coap_pdu_t *pdu, + size_t len, + const unsigned char *data); + +/** + * Adds option of given type to pdu that is passed as first + * parameter. + * coap_add_option() destroys the PDU's data, so coap_add_data() must be called + * after all options have been added. As coap_add_token() destroys the options + * following the token, the token must be added before coap_add_option() is + * called. This function returns the number of bytes written or @c 0 on error. + */ +size_t coap_add_option(coap_pdu_t *pdu, + unsigned short type, + unsigned int len, + const unsigned char *data); + +/** + * Adds option of given type to pdu that is passed as first parameter, but does + * not write a value. It works like coap_add_option with respect to calling + * sequence (i.e. after token and before data). This function returns a memory + * address to which the option data has to be written before the PDU can be + * sent, or @c NULL on error. + */ +unsigned char *coap_add_option_later(coap_pdu_t *pdu, + unsigned short type, + unsigned int len); + +/** + * Adds given data to the pdu that is passed as first parameter. Note that the + * PDU's data is destroyed by coap_add_option(). coap_add_data() must be called + * only once per PDU, otherwise the result is undefined. + */ +int coap_add_data(coap_pdu_t *pdu, + unsigned int len, + const unsigned char *data); + +/** + * Retrieves the length and data pointer of specified PDU. Returns 0 on error or + * 1 if *len and *data have correct values. Note that these values are destroyed + * with the pdu. + */ +int coap_get_data(coap_pdu_t *pdu, + size_t *len, + unsigned char **data); + +#endif /* _COAP_PDU_H_ */ diff --git a/tools/sdk/include/coap/coap/prng.h b/tools/sdk/include/coap/coap/prng.h new file mode 100644 index 00000000..da6d9534 --- /dev/null +++ b/tools/sdk/include/coap/coap/prng.h @@ -0,0 +1,106 @@ +/* + * prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef _COAP_PRNG_H_ +#define _COAP_PRNG_H_ + +/** + * @defgroup prng Pseudo Random Numbers + * @{ + */ + +#if defined(WITH_POSIX) || (defined(WITH_LWIP) && !defined(LWIP_RAND)) +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +static inline int +coap_prng_impl(unsigned char *buf, size_t len) { + while (len--) + *buf++ = rand() & 0xFF; + return 1; +} +#endif /* WITH_POSIX */ + +#ifdef WITH_CONTIKI +#include + +/** + * Fills \p buf with \p len random bytes. This is the default implementation for + * prng(). You might want to change prng() to use a better PRNG on your specific + * platform. + */ +static inline int +contiki_prng_impl(unsigned char *buf, size_t len) { + unsigned short v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) contiki_prng_impl((Buf), (Length)) +#define prng_init(Value) random_init((unsigned short)(Value)) +#endif /* WITH_CONTIKI */ + +#if defined(WITH_LWIP) && defined(LWIP_RAND) +static inline int +lwip_prng_impl(unsigned char *buf, size_t len) { + u32_t v = LWIP_RAND(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = LWIP_RAND(); + } + + memcpy(buf, &v, len); + return 1; +} + +#define prng(Buf,Length) lwip_prng_impl((Buf), (Length)) +#define prng_init(Value) + +#endif /* WITH_LWIP */ + +#ifndef prng +/** + * Fills \p Buf with \p Length bytes of random data. + * + * @hideinitializer + */ +#define prng(Buf,Length) coap_prng_impl((Buf), (Length)) +#endif + +#ifndef prng_init +/** + * Called to set the PRNG seed. You may want to re-define this to allow for a + * better PRNG. + * + * @hideinitializer + */ +#define prng_init(Value) srand((unsigned long)(Value)) +#endif + +/** @} */ + +#endif /* _COAP_PRNG_H_ */ diff --git a/tools/sdk/include/coap/coap/resource.h b/tools/sdk/include/coap/coap/resource.h new file mode 100644 index 00000000..dbb19a8d --- /dev/null +++ b/tools/sdk/include/coap/coap/resource.h @@ -0,0 +1,408 @@ +/* + * resource.h -- generic resource handling + * + * Copyright (C) 2010,2011,2014,2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +/** + * @file resource.h + * @brief Generic resource handling + */ + +#ifndef _COAP_RESOURCE_H_ +#define _COAP_RESOURCE_H_ + +# include + +#ifndef COAP_RESOURCE_CHECK_TIME +/** The interval in seconds to check if resources have changed. */ +#define COAP_RESOURCE_CHECK_TIME 2 +#endif /* COAP_RESOURCE_CHECK_TIME */ + +#ifdef COAP_RESOURCES_NOHASH +# include "utlist.h" +#else +# include "uthash.h" +#endif + +#include "hashkey.h" +#include "async.h" +#include "str.h" +#include "pdu.h" +#include "net.h" +#include "subscribe.h" + +/** + * Definition of message handler function (@sa coap_resource_t). + */ +typedef void (*coap_method_handler_t) + (coap_context_t *, + struct coap_resource_t *, + const coap_endpoint_t *, + coap_address_t *, + coap_pdu_t *, + str * /* token */, + coap_pdu_t * /* response */); + +#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1 +#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2 + +typedef struct coap_attr_t { + struct coap_attr_t *next; + str name; + str value; + int flags; +} coap_attr_t; + +/** The URI passed to coap_resource_init() is free'd by coap_delete_resource(). */ +#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1 + +/** + * Notifications will be sent non-confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_NON 0x0 + +/** + * Notifications will be sent confirmable by default. RFC 7641 Section 4.5 + * https://tools.ietf.org/html/rfc7641#section-4.5 + */ +#define COAP_RESOURCE_FLAGS_NOTIFY_CON 0x2 + +typedef struct coap_resource_t { + unsigned int dirty:1; /**< set to 1 if resource has changed */ + unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet + * been notified of the last change */ + unsigned int observable:1; /**< can be observed */ + unsigned int cacheable:1; /**< can be cached */ + + /** + * Used to store handlers for the four coap methods @c GET, @c POST, @c PUT, + * and @c DELETE. coap_dispatch() will pass incoming requests to the handler + * that corresponds to its request method or generate a 4.05 response if no + * handler is available. + */ + coap_method_handler_t handler[4]; + + coap_key_t key; /**< the actual key bytes for this resource */ + +#ifdef COAP_RESOURCES_NOHASH + struct coap_resource_t *next; +#else + UT_hash_handle hh; +#endif + + coap_attr_t *link_attr; /**< attributes to be included with the link format */ + coap_subscription_t *subscribers; /**< list of observers for this resource */ + + /** + * Request URI for this resource. This field will point into the static + * memory. + */ + str uri; + int flags; + +} coap_resource_t; + +/** + * Creates a new resource object and initializes the link field to the string + * of length @p len. This function returns the new coap_resource_t object. + * + * @param uri The URI path of the new resource. + * @param len The length of @p uri. + * @param flags Flags for memory management (in particular release of memory). + * + * @return A pointer to the new object or @c NULL on error. + */ +coap_resource_t *coap_resource_init(const unsigned char *uri, + size_t len, int flags); + + +/** + * Sets the notification message type of resource @p r to given + * @p mode which must be one of @c COAP_RESOURCE_FLAGS_NOTIFY_NON + * or @c COAP_RESOURCE_FLAGS_NOTIFY_CON. + */ +static inline void +coap_resource_set_mode(coap_resource_t *r, int mode) { + r->flags = (r->flags & !COAP_RESOURCE_FLAGS_NOTIFY_CON) | mode; +} + +/** + * Registers the given @p resource for @p context. The resource must have been + * created by coap_resource_init(), the storage allocated for the resource will + * be released by coap_delete_resource(). + * + * @param context The context to use. + * @param resource The resource to store. + */ +void coap_add_resource(coap_context_t *context, coap_resource_t *resource); + +/** + * Deletes a resource identified by @p key. The storage allocated for that + * resource is freed. + * + * @param context The context where the resources are stored. + * @param key The unique key for the resource to delete. + * + * @return @c 1 if the resource was found (and destroyed), + * @c 0 otherwise. + */ +int coap_delete_resource(coap_context_t *context, coap_key_t key); + +/** + * Deletes all resources from given @p context and frees their storage. + * + * @param context The CoAP context with the resources to be deleted. + */ +void coap_delete_all_resources(coap_context_t *context); + +/** + * Registers a new attribute with the given @p resource. As the + * attributes str fields will point to @p name and @p val the + * caller must ensure that these pointers are valid during the + * attribute's lifetime. + * + * @param resource The resource to register the attribute with. + * @param name The attribute's name. + * @param nlen Length of @p name. + * @param val The attribute's value or @c NULL if none. + * @param vlen Length of @p val if specified. + * @param flags Flags for memory management (in particular release of + * memory). + * + * @return A pointer to the new attribute or @c NULL on error. + */ +coap_attr_t *coap_add_attr(coap_resource_t *resource, + const unsigned char *name, + size_t nlen, + const unsigned char *val, + size_t vlen, + int flags); + +/** + * Returns @p resource's coap_attr_t object with given @p name if found, @c NULL + * otherwise. + * + * @param resource The resource to search for attribute @p name. + * @param name Name of the requested attribute. + * @param nlen Actual length of @p name. + * @return The first attribute with specified @p name or @c NULL if none + * was found. + */ +coap_attr_t *coap_find_attr(coap_resource_t *resource, + const unsigned char *name, + size_t nlen); + +/** + * Deletes an attribute. + * + * @param attr Pointer to a previously created attribute. + * + */ +void coap_delete_attr(coap_attr_t *attr); + +/** + * Status word to encode the result of conditional print or copy operations such + * as coap_print_link(). The lower 28 bits of coap_print_status_t are used to + * encode the number of characters that has actually been printed, bits 28 to 31 + * encode the status. When COAP_PRINT_STATUS_ERROR is set, an error occurred + * during output. In this case, the other bits are undefined. + * COAP_PRINT_STATUS_TRUNC indicates that the output is truncated, i.e. the + * printing would have exceeded the current buffer. + */ +typedef unsigned int coap_print_status_t; + +#define COAP_PRINT_STATUS_MASK 0xF0000000u +#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK) +#define COAP_PRINT_STATUS_ERROR 0x80000000u +#define COAP_PRINT_STATUS_TRUNC 0x40000000u + +/** + * Writes a description of this resource in link-format to given text buffer. @p + * len must be initialized to the maximum length of @p buf and will be set to + * the number of characters actually written if successful. This function + * returns @c 1 on success or @c 0 on error. + * + * @param resource The resource to describe. + * @param buf The output buffer to write the description to. + * @param len Must be initialized to the length of @p buf and + * will be set to the length of the printed link description. + * @param offset The offset within the resource description where to + * start writing into @p buf. This is useful for dealing + * with the Block2 option. @p offset is updated during + * output as it is consumed. + * + * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, + * the lower 28 bits will indicate the number of characters that + * have actually been output into @p buffer. The flag + * COAP_PRINT_STATUS_TRUNC indicates that the output has been + * truncated. + */ +coap_print_status_t coap_print_link(const coap_resource_t *resource, + unsigned char *buf, + size_t *len, + size_t *offset); + +/** + * Registers the specified @p handler as message handler for the request type @p + * method + * + * @param resource The resource for which the handler shall be registered. + * @param method The CoAP request method to handle. + * @param handler The handler to register with @p resource. + */ +static inline void +coap_register_handler(coap_resource_t *resource, + unsigned char method, + coap_method_handler_t handler) { + assert(resource); + assert(method > 0 && (size_t)(method-1) < sizeof(resource->handler)/sizeof(coap_method_handler_t)); + resource->handler[method-1] = handler; +} + +/** + * Returns the resource identified by the unique string @p key. If no resource + * was found, this function returns @c NULL. + * + * @param context The context to look for this resource. + * @param key The unique key of the resource. + * + * @return A pointer to the resource or @c NULL if not found. + */ +coap_resource_t *coap_get_resource_from_key(coap_context_t *context, + coap_key_t key); + +/** + * Calculates the hash key for the resource requested by the Uri-Options of @p + * request. This function calls coap_hash() for every path segment. + * + * @param request The requesting pdu. + * @param key The resulting hash is stored in @p key. + */ +void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); + +/** + * @addtogroup observe + */ + +/** + * Adds the specified peer as observer for @p resource. The subscription is + * identified by the given @p token. This function returns the registered + * subscription information if the @p observer has been added, or @c NULL on + * error. + * + * @param resource The observed resource. + * @param local_interface The local network interface where the observer is + * attached to. + * @param observer The remote peer that wants to received status updates. + * @param token The token that identifies this subscription. + * @return A pointer to the added/updated subscription + * information or @c NULL on error. + */ +coap_subscription_t *coap_add_observer(coap_resource_t *resource, + const coap_endpoint_t *local_interface, + const coap_address_t *observer, + const str *token); + +/** + * Returns a subscription object for given @p peer. + * + * @param resource The observed resource. + * @param peer The address to search for. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return A valid subscription if exists or @c NULL otherwise. + */ +coap_subscription_t *coap_find_observer(coap_resource_t *resource, + const coap_address_t *peer, + const str *token); + +/** + * Marks an observer as alive. + * + * @param context The CoAP context to use. + * @param observer The transport address of the observer. + * @param token The corresponding token that has been used for the + * subscription. + */ +void coap_touch_observer(coap_context_t *context, + const coap_address_t *observer, + const str *token); + +/** + * Removes any subscription for @p observer from @p resource and releases the + * allocated storage. The result is @c 1 if an observation relationship with @p + * observer and @p token existed, @c 0 otherwise. + * + * @param resource The observed resource. + * @param observer The observer's address. + * @param token The token that identifies this subscription or @c NULL for + * any token. + * @return @c 1 if the observer has been deleted, @c 0 otherwise. + */ +int coap_delete_observer(coap_resource_t *resource, + const coap_address_t *observer, + const str *token); + +/** + * Checks for all known resources, if they are dirty and notifies subscribed + * observers. + */ +void coap_check_notify(coap_context_t *context); + +#ifdef COAP_RESOURCES_NOHASH + +#define RESOURCES_ADD(r, obj) \ + LL_PREPEND((r), (obj)) + +#define RESOURCES_DELETE(r, obj) \ + LL_DELETE((r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp; \ + LL_FOREACH((r), tmp) + +#define RESOURCES_FIND(r, k, res) { \ + coap_resource_t *tmp; \ + (res) = tmp = NULL; \ + LL_FOREACH((r), tmp) { \ + if (memcmp((k), tmp->key, sizeof(coap_key_t)) == 0) { \ + (res) = tmp; \ + break; \ + } \ + } \ + } +#else /* COAP_RESOURCES_NOHASH */ + +#define RESOURCES_ADD(r, obj) \ + HASH_ADD(hh, (r), key, sizeof(coap_key_t), (obj)) + +#define RESOURCES_DELETE(r, obj) \ + HASH_DELETE(hh, (r), (obj)) + +#define RESOURCES_ITER(r,tmp) \ + coap_resource_t *tmp, *rtmp; \ + HASH_ITER(hh, (r), tmp, rtmp) + +#define RESOURCES_FIND(r, k, res) { \ + HASH_FIND(hh, (r), (k), sizeof(coap_key_t), (res)); \ + } + +#endif /* COAP_RESOURCES_NOHASH */ + +/** @} */ + +coap_print_status_t coap_print_wellknown(coap_context_t *, + unsigned char *, + size_t *, size_t, + coap_opt_t *); + +void coap_handle_failed_notify(coap_context_t *, + const coap_address_t *, + const str *); + +#endif /* _COAP_RESOURCE_H_ */ diff --git a/tools/sdk/include/coap/coap/str.h b/tools/sdk/include/coap/coap/str.h new file mode 100644 index 00000000..3dfa6731 --- /dev/null +++ b/tools/sdk/include/coap/coap/str.h @@ -0,0 +1,33 @@ +/* + * str.h -- strings to be used in the CoAP library + * + * Copyright (C) 2010-2011 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_STR_H_ +#define _COAP_STR_H_ + +#include + +typedef struct { + size_t length; /* length of string */ + unsigned char *s; /* string data */ +} str; + +#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); } + +/** + * Returns a new string object with at least size bytes storage allocated. The + * string must be released using coap_delete_string(); + */ +str *coap_new_string(size_t size); + +/** + * Deletes the given string and releases any memory allocated. + */ +void coap_delete_string(str *); + +#endif /* _COAP_STR_H_ */ diff --git a/tools/sdk/include/coap/coap/subscribe.h b/tools/sdk/include/coap/coap/subscribe.h new file mode 100644 index 00000000..52068642 --- /dev/null +++ b/tools/sdk/include/coap/coap/subscribe.h @@ -0,0 +1,72 @@ +/* + * subscribe.h -- subscription handling for CoAP + * see draft-ietf-core-observe-16 + * + * Copyright (C) 2010-2012,2014-2015 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + + +#ifndef _COAP_SUBSCRIBE_H_ +#define _COAP_SUBSCRIBE_H_ + +#include "address.h" +#include "coap_io.h" + +/** + * @defgroup observe Resource observation + * @{ + */ + +/** + * The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe + * relationship for (sender address, token) is requested. + */ +#define COAP_OBSERVE_ESTABLISH 0 + +/** + * The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe + * relationship for (sender address, token) must be cancelled. + */ +#define COAP_OBSERVE_CANCEL 1 + +#ifndef COAP_OBS_MAX_NON +/** + * Number of notifications that may be sent non-confirmable before a confirmable + * message is sent to detect if observers are alive. The maximum allowed value + * here is @c 15. + */ +#define COAP_OBS_MAX_NON 5 +#endif /* COAP_OBS_MAX_NON */ + +#ifndef COAP_OBS_MAX_FAIL +/** + * Number of confirmable notifications that may fail (i.e. time out without + * being ACKed) before an observer is removed. The maximum value for + * COAP_OBS_MAX_FAIL is @c 3. + */ +#define COAP_OBS_MAX_FAIL 3 +#endif /* COAP_OBS_MAX_FAIL */ + +/** Subscriber information */ +typedef struct coap_subscription_t { + struct coap_subscription_t *next; /**< next element in linked list */ + coap_endpoint_t local_if; /**< local communication interface */ + coap_address_t subscriber; /**< address and port of subscriber */ + + unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */ + unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */ + unsigned int dirty:1; /**< set if the notification temporarily could not be + * sent (in that case, the resource's partially + * dirty flag is set too) */ + size_t token_length; /**< actual length of token */ + unsigned char token[8]; /**< token used for subscription */ +} coap_subscription_t; + +void coap_subscription_init(coap_subscription_t *); + +/** @} */ + +#endif /* _COAP_SUBSCRIBE_H_ */ diff --git a/tools/sdk/include/coap/coap/uri.h b/tools/sdk/include/coap/coap/uri.h new file mode 100644 index 00000000..2340a7a6 --- /dev/null +++ b/tools/sdk/include/coap/coap/uri.h @@ -0,0 +1,121 @@ +/* + * uri.h -- helper functions for URI treatment + * + * Copyright (C) 2010-2011,2016 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _COAP_URI_H_ +#define _COAP_URI_H_ + +#include "hashkey.h" +#include "str.h" + +/** + * Representation of parsed URI. Components may be filled from a string with + * coap_split_uri() and can be used as input for option-creation functions. + */ +typedef struct { + str host; /**< host part of the URI */ + unsigned short port; /**< The port in host byte order */ + str path; /**< Beginning of the first path segment. + Use coap_split_path() to create Uri-Path options */ + str query; /**< The query part if present */ +} coap_uri_t; + +/** + * Creates a new coap_uri_t object from the specified URI. Returns the new + * object or NULL on error. The memory allocated by the new coap_uri_t + * must be released using coap_free(). + * + * @param uri The URI path to copy. + * @param length The length of uri. + * + * @return New URI object or NULL on error. + */ +coap_uri_t *coap_new_uri(const unsigned char *uri, unsigned int length); + +/** + * Clones the specified coap_uri_t object. Thie function allocates sufficient + * memory to hold the coap_uri_t structure and its contents. The object must + * be released with coap_free(). */ +coap_uri_t *coap_clone_uri(const coap_uri_t *uri); + +/** + * Calculates a hash over the given path and stores the result in + * @p key. This function returns @c 0 on error or @c 1 on success. + * + * @param path The URI path to generate hash for. + * @param len The length of @p path. + * @param key The output buffer. + * + * @return @c 1 if @p key was set, @c 0 otherwise. + */ +int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); + +/** + * @defgroup uri_parse URI Parsing Functions + * + * CoAP PDUs contain normalized URIs with their path and query split into + * multiple segments. The functions in this module help splitting strings. + * @{ + */ + +/** + * Parses a given string into URI components. The identified syntactic + * components are stored in the result parameter @p uri. Optional URI + * components that are not specified will be set to { 0, 0 }, except for the + * port which is set to @c COAP_DEFAULT_PORT. This function returns @p 0 if + * parsing succeeded, a value less than zero otherwise. + * + * @param str_var The string to split up. + * @param len The actual length of @p str_var + * @param uri The coap_uri_t object to store the result. + * @return @c 0 on success, or < 0 on error. + * + */ +int coap_split_uri(const unsigned char *str_var, size_t len, coap_uri_t *uri); + +/** + * Splits the given URI path into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective segment after percent-decoding. + * + * @param s The path string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + */ +int coap_split_path(const unsigned char *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** + * Splits the given URI query into segments. Each segment is preceded + * by an option pseudo-header with delta-value 0 and the actual length + * of the respective query term. + * + * @param s The query string to split. + * @param length The actual length of @p s. + * @param buf Result buffer for parsed segments. + * @param buflen Maximum length of @p buf. Will be set to the actual number + * of bytes written into buf on success. + * + * @return The number of segments created or @c -1 on error. + * + * @bug This function does not reserve additional space for delta > 12. + */ +int coap_split_query(const unsigned char *s, + size_t length, + unsigned char *buf, + size_t *buflen); + +/** @} */ + +#endif /* _COAP_URI_H_ */ diff --git a/tools/sdk/include/coap/coap/uthash.h b/tools/sdk/include/coap/coap/uthash.h new file mode 100644 index 00000000..32b7a81c --- /dev/null +++ b/tools/sdk/include/coap/coap/uthash.h @@ -0,0 +1,963 @@ +/* +Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ +#include /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#define DECLTYPE(x) +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined (_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#else +#include +#endif + +#define UTHASH_VERSION 1.9.9 + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + out=NULL; \ + if (head) { \ + unsigned _hf_bkt,_hf_hashv; \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0 +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + replaced=NULL; \ + HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ + if (replaced!=NULL) { \ + HASH_DELETE(hh,head,replaced); \ + }; \ + HASH_ADD(hh,head,fieldname,keylen_in,add); \ +} while(0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)(keyptr); \ + (add)->hh.keylen = (unsigned)(keylen_in); \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + unsigned _hd_bkt; \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count; \ + char *_prev; \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619; \ + } \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned char *_hj_key=(unsigned char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + /* case 0: nothing left to add */ \ + default: /* make gcc -Wswitch-default happy */ \ + ; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned char *_sfh_key=(unsigned char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if ((out)->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e) { \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#define HASH_OVERHEAD(hh,head) \ + ((head) ? ( \ + (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + (sizeof(UT_hash_table)) + \ + (HASH_BLOOM_BYTELEN)))) : 0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/tools/sdk/include/coap/coap/utlist.h b/tools/sdk/include/coap/coap/utlist.h new file mode 100644 index 00000000..b5f3f04c --- /dev/null +++ b/tools/sdk/include/coap/coap/utlist.h @@ -0,0 +1,757 @@ +/* +Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 1.9.9 + +#include + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ code), this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#endif +#elif defined(__ICCARM__) +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define _NEXT(elt,list,next) ((char*)((list)->next)) +#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define _SV(elt,list) +#define _NEXT(elt,list,next) ((elt)->next) +#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define _PREV(elt,list,prev) ((elt)->prev) */ +#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define _RS(list) +#define _CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev, _ls_tail); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); \ + if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = _NEXT(_ls_q,list,next); \ + } \ + _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev,_ls_tail); \ + _CASTASGN(_tmp,list); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = head1; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ +#define LL_APPEND_VS2008(head,add) \ + LL_APPEND2_VS2008(head,add,next) + +#define LL_APPEND2_VS2008(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#define LL_DELETE_VS2008(head,del) \ + LL_DELETE2_VS2008(head,del,next) + +#define LL_DELETE2_VS2008(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + head = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char**)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ +} while (0) +#ifdef NO_DECLTYPE +#undef LL_APPEND +#define LL_APPEND LL_APPEND_VS2008 +#undef LL_DELETE +#define LL_DELETE LL_DELETE_VS2008 +#undef LL_DELETE2 +#define LL_DELETE2 LL_DELETE2_VS2008 +#undef LL_APPEND2 +#define LL_APPEND2 LL_APPEND2_VS2008 +#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ +#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ +#endif +/* end VS2008 replacements */ + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + LL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define LL_REPLACE_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_PREPEND_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) \ + + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + _tmp = (head2)->prev; \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + (head1)->prev = _tmp; \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + DL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ +} while (0) \ + + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ +(head)=(add); \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if ( ((head)==(del)) && ((head)->next == (head))) { \ + (head) = 0L; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +{ \ + counter = 0; \ + CDL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ + (el) && ((tmp2)=(el)->next, 1); \ + ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define CDL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ +} while (0) \ + +#endif /* UTLIST_H */ + diff --git a/tools/sdk/include/coap/coap_config.h b/tools/sdk/include/coap/coap_config.h new file mode 100644 index 00000000..db314f2d --- /dev/null +++ b/tools/sdk/include/coap/coap_config.h @@ -0,0 +1,39 @@ +/* + * libcoap configure implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * configure operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#ifdef WITH_POSIX +#include "coap_config_posix.h" +#endif + +#define HAVE_STDIO_H +#define HAVE_ASSERT_H + +#define PACKAGE_STRING PACKAGE_NAME PACKAGE_VERSION + +/* it's just provided by libc. i hope we don't get too many of those, as + * actually we'd need autotools again to find out what environment we're + * building in */ +#define HAVE_STRNLEN 1 + +#define HAVE_LIMITS_H + +#define COAP_RESOURCES_NOHASH + +#endif /* _CONFIG_H_ */ diff --git a/tools/sdk/include/coap/coap_config_posix.h b/tools/sdk/include/coap/coap_config_posix.h new file mode 100644 index 00000000..a77e97f0 --- /dev/null +++ b/tools/sdk/include/coap/coap_config_posix.h @@ -0,0 +1,41 @@ +/* + * libcoap configure implementation for ESP32 platform. + * + * Uses libcoap software implementation for failover when concurrent + * configure operations are in use. + * + * coap.h -- main header file for CoAP stack of libcoap + * + * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * 2015 Carsten Schoenert + * + * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD + * + * This file is part of the CoAP library libcoap. Please see README for terms + * of use. + */ + +#ifndef COAP_CONFIG_POSIX_H_ +#define COAP_CONFIG_POSIX_H_ + +#ifdef WITH_POSIX + +#include + +#define HAVE_SYS_SOCKET_H +#define HAVE_MALLOC +#define HAVE_ARPA_INET_H + +#define IP_PKTINFO IP_MULTICAST_IF +#define IPV6_PKTINFO IPV6_V6ONLY + +#define PACKAGE_NAME "libcoap-posix" +#define PACKAGE_VERSION "?" + +#define CUSTOM_COAP_NETWORK_ENDPOINT +#define CUSTOM_COAP_NETWORK_SEND +#define CUSTOM_COAP_NETWORK_READ + +#endif + +#endif /* COAP_CONFIG_POSIX_H_ */ diff --git a/tools/sdk/include/config/sdkconfig.h b/tools/sdk/include/config/sdkconfig.h index c1d6627d..92dbc258 100644 --- a/tools/sdk/include/config/sdkconfig.h +++ b/tools/sdk/include/config/sdkconfig.h @@ -7,7 +7,6 @@ #define CONFIG_ESP32_PHY_MAX_TX_POWER 20 #define CONFIG_TRACEMEM_RESERVE_DRAM 0x0 #define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE 1 -#define CONFIG_MEMMAP_BT 1 #define CONFIG_ESPTOOLPY_FLASHSIZE_4MB 1 #define CONFIG_ESPTOOLPY_FLASHFREQ "80m" #define CONFIG_NEWLIB_STDOUT_ADDCR 1 @@ -20,7 +19,6 @@ #define CONFIG_LOG_BOOTLOADER_LEVEL_ERROR 1 #define CONFIG_CONSOLE_UART_BAUDRATE 115200 #define CONFIG_LWIP_MAX_SOCKETS 4 -#define CONFIG_ESP32_ENABLE_STACK_BT 1 #define CONFIG_EMAC_TASK_PRIORITY 20 #define CONFIG_ULP_COPROC_RESERVE_MEM 512 #define CONFIG_ESPTOOLPY_BAUD 921600 @@ -33,9 +31,9 @@ #define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384 #define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1 #define CONFIG_AUTOSTART_ARDUINO 1 -#define CONFIG_ESP32_ENABLE_STACK_WIFI 1 #define CONFIG_LOG_DEFAULT_LEVEL_ERROR 1 #define CONFIG_MBEDTLS_MPI_USE_INTERRUPT 1 +#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1 #define CONFIG_MAIN_TASK_STACK_SIZE 4096 #define CONFIG_ESPTOOLPY_FLASHMODE "dio" #define CONFIG_BTC_TASK_STACK_SIZE 2048 @@ -76,14 +74,15 @@ #define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv" #define CONFIG_MBEDTLS_HAVE_TIME 1 #define CONFIG_FREERTOS_ISR_STACKSIZE 1536 +#define CONFIG_OPTIMIZATION_LEVEL_DEBUG 1 #define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32 +#define CONFIG_ESP32_WIFI_RX_BUFFER_NUM 25 #define CONFIG_ESPTOOLPY_BAUD_921600B 1 #define CONFIG_APP_OFFSET 0x10000 #define CONFIG_MEMMAP_SMP 1 #define CONFIG_LWIP_SO_RCVBUF 1 #define CONFIG_MBEDTLS_HARDWARE_MPI 1 #define CONFIG_MONITOR_BAUD_OTHER_VAL 115200 -#define CONFIG_ESPTOOLPY_PORT "/dev/tty.SLAB_USBtoUART" -#define CONFIG_OPTIMIZATION_LEVEL_RELEASE 1 +#define CONFIG_ESPTOOLPY_PORT "/dev/cu.usbserial-0040121AB" #define CONFIG_ESP32_PANIC_PRINT_HALT 1 #define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR 1 diff --git a/tools/sdk/include/driver/driver/i2c.h b/tools/sdk/include/driver/driver/i2c.h index 69b80b1e..960ec61d 100644 --- a/tools/sdk/include/driver/driver/i2c.h +++ b/tools/sdk/include/driver/driver/i2c.h @@ -401,7 +401,7 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period); * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ -esp_err_t i2s_get_period(i2c_port_t i2c_num, int* high_period, int* low_period); +esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period); /** * @brief set I2C master start signal timing diff --git a/tools/sdk/include/driver/driver/ledc.h b/tools/sdk/include/driver/driver/ledc.h index 691379a3..af7c6b80 100644 --- a/tools/sdk/include/driver/driver/ledc.h +++ b/tools/sdk/include/driver/driver/ledc.h @@ -16,9 +16,6 @@ #define _DRIVER_LEDC_H_ #include "esp_err.h" #include "soc/soc.h" -#include "soc/ledc_reg.h" -#include "soc/ledc_reg.h" -#include "soc/ledc_struct.h" #include "driver/gpio.h" #include "driver/periph_ctrl.h" #include "esp_intr_alloc.h" @@ -68,6 +65,7 @@ typedef enum { LEDC_CHANNEL_5, /*!< LEDC channel 5 */ LEDC_CHANNEL_6, /*!< LEDC channel 6 */ LEDC_CHANNEL_7, /*!< LEDC channel 7 */ + LEDC_CHANNEL_MAX, } ledc_channel_t; typedef enum { @@ -79,6 +77,11 @@ typedef enum { LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */ } ledc_timer_bit_t; +typedef enum { + LEDC_FADE_NO_WAIT = 0, /*!< LEDC fade function will return immediately */ + LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty*/ + LEDC_FADE_MAX, +} ledc_fade_mode_t; /** * @brief Configuration parameters of LEDC channel for ledc_channel_config function */ @@ -104,43 +107,39 @@ typedef struct { typedef intr_handle_t ledc_isr_handle_t; /** - * @brief LEDC channel configuration + * @brief LEDC channel configuration + * Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth * - * User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth + * @param ledc_conf Pointer of LEDC channel configure struct * - * @param ledc_conf Pointer of LEDC channel configure struct * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error - * */ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf); /** - * @brief LEDC timer configuration - * - * User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num + * @brief LEDC timer configuration + * Configure LEDC timer with the given source timer/frequency(Hz)/bit_num * * @param timer_conf Pointer of LEDC timer configure struct * - * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num. - * */ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf); /** - * @brief LEDC update channel parameters + * @brief LEDC update channel parameters + * Call this function to activate the LEDC updated parameters. + * After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings. * - * Call this function to activate the LEDC updated parameters. - * After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings. - * - * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * - * @param channel LEDC channel(0-7), select from ledc_channel_t + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, + * now we only support high-speed mode. + * We will access low-speed mode in next version + * @param channel LEDC channel(0-7), select from ledc_channel_t * * @return * - ESP_OK Success @@ -150,14 +149,11 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf); esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); /** - * @brief LEDC stop - * - * Disable LEDC output, and set idle level + * @brief LEDC stop. + * Disable LEDC output, and set idle level * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param channel LEDC channel(0-7), select from ledc_channel_t - * * @param idle_level Set output idle level after LEDC stops. * * @return @@ -167,14 +163,10 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level); /** - * @brief LEDC set channel frequency(Hz) - * - * Set LEDC frequency(Hz) + * @brief LEDC set channel frequency(Hz) * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param timer_num LEDC timer index(0-3), select from ledc_timer_t - * * @param freq_hz Set the LEDC frequency * * @return @@ -188,25 +180,20 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t * @brief LEDC get channel frequency(Hz) * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param timer_num LEDC timer index(0-3), select from ledc_timer_t * * @return * - 0 error * - Others Current LEDC frequency - * */ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); /** - * @brief LEDC set duty - * - * Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect. + * @brief LEDC set duty + * Only after calling ledc_update_duty will the duty update. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param channel LEDC channel(0-7), select from ledc_channel_t - * * @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1] * * @return @@ -216,37 +203,27 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty); /** - * @brief LEDC get duty + * @brief LEDC get duty * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param channel LEDC channel(0-7), select from ledc_channel_t * - * * @return * - (-1) parameter error * - Others Current LEDC duty - * */ int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); /** - * @brief LEDC set gradient - * - * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. + * @brief LEDC set gradient + * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param channel LEDC channel(0-7), select from ledc_channel_t - * * @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1] - * * @param gradule_direction Set the direction of the gradient - * * @param step_num Set the number of the gradient - * * @param duty_cyle_num Set how many LEDC tick each time the gradient lasts - * * @param duty_scale Set gradient change amplitude * * @return @@ -257,16 +234,16 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale); /** - * @brief register LEDC interrupt handler, the handler is an ISR. - * The handler will be attached to the same CPU core that this function is running on. + * @brief Register LEDC interrupt handler, the handler is an ISR. + * The handler will be attached to the same CPU core that this function is running on. * - * @param fn Interrupt handler function. - * @param arg User-supplied argument passed to the 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 arg Parameter for handler function - * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will - * be returned here. + * @param fn Interrupt handler function. + * @param arg User-supplied argument passed to the 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 arg Parameter for handler function + * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will + * be returned here. * * @return * - ESP_OK Success @@ -275,48 +252,38 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, ledc_isr_handle_t *handle); /** - * @brief configure LEDC settings + * @brief Configure LEDC settings * - * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * - * @param timer_sel Timer index(0-3), there are 4 timers in LEDC module - * - * @param div_num Timer clock divide number, the timer clock is divided from the selected clock source - * - * @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1) - * - * @param clk_src Select LEDC source clock. + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param timer_sel Timer index(0-3), there are 4 timers in LEDC module + * @param div_num Timer clock divide number, the timer clock is divided from the selected clock source + * @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1) + * @param clk_src Select LEDC source clock. * * @return * - (-1) Parameter error * - Other Current LEDC duty - * */ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src); /** - * @brief reset LEDC timer + * @brief Reset LEDC timer * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * - * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success - * */ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel); /** - * @brief pause LEDC timer counter + * @brief Pause LEDC timer counter * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * - * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success @@ -325,104 +292,96 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel); esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel); /** - * @brief pause LEDC timer resume - * - * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * - * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t + * @brief Resume LEDC timer * + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success - * */ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel); /** - * @brief bind LEDC channel with the selected timer - * - * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version - * - * @param channel LEDC channel index(0-7), select from ledc_channel_t - * - * @param timer_idx LEDC timer index(0-3), select from ledc_timer_t + * @brief Bind LEDC channel with the selected timer * + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param channel LEDC channel index(0-7), select from ledc_channel_t + * @param timer_idx LEDC timer index(0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success + */ +esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx); + +/** + * @brief Set LEDC fade function. Should call ledc_fade_func_install() before calling this function. + * Call ledc_fade_start() after this to start fading. + * + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, + * For now we only support high-speed mode. We will access low-speed mode soon. + * @param channel LEDC channel index(0-7), select from ledc_channel_t + * @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1))) + * @param scale Controls the increase or decrease step scale. + * @param cycle_num increase or decrease the duty every cycle_num cycles + * + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + * - ESP_ERR_INVALID_STATE Fade function not installed. + */ +esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, int target_duty, int scale, int cycle_num); + +/** + * @brief Set LEDC fade function, with a limited time. Should call ledc_fade_func_install() before calling this function. + * Call ledc_fade_start() after this to start fading. + * + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, + * For now we only support high-speed mode. We will access low-speed mode soon. + * @param channel LEDC channel index(0-7), select from ledc_channel_t + * @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1))) + * @param max_fade_time_ms The maximum time of the fading ( ms ). + * + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + * - ESP_ERR_INVALID_STATE Fade function not installed. + */ +esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, int target_duty, int max_fade_time_ms); + +/** + * @brief Install ledc fade function. This function will occupy interrupt of LEDC module. + * + * @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. + * + * @return + * - ESP_ERR_NO_MEM No enough memory + * - ESP_OK Success + * - ESP_ERR_INVALID_STATE Fade function already installed. + */ +esp_err_t ledc_fade_func_install(int intr_alloc_flags); + +/** + * @brief Uninstall LEDC fade function. * */ -esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t timer_idx); +void ledc_fade_func_uninstall(); -/***************************EXAMPLE********************************** +/** + * @brief Start LEDC fading. * + * @param channel LEDC channel number + * @param wait_done Whether to block until fading done. * - * ----------------EXAMPLE OF LEDC SETTING --------------------- - * @code{c} - * //1. enable LEDC - * //enable LEDC module, or you can not set any register of it. - * periph_module_enable(PERIPH_LEDC_MODULE); - * @endcode - * - * @code{c} - * //2. set LEDC timer - * ledc_timer_config_t timer_conf = { - * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number - * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz - * .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode, - * .timer_num = LEDC_TIMER_0, //timer number - * }; - * ledc_timer_config(&timer_conf); //setup timer. - * @endcode - * - * @code{c} - * //3. set LEDC channel - * ledc_channel_config_t ledc_conf = { - * .channel = LEDC_CHANNEL_0; //set LEDC channel 0 - * .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) - * .gpio_num = 16; //GPIO number - * .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. - * .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t - * .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same - * } - * ledc_channel_config(&ledc_conf); //setup the configuration - * - * ----------------EXAMPLE OF SETTING DUTY --- ----------------- - * @code{c} - * ledc_channel_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73) - * uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1) - * LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty. - * ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings. - * @endcode - * - * ----------------EXAMPLE OF LEDC INTERRUPT ------------------ - * @code{c} - * //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here. - * ledc_isr_register(ledc_isr_handler, NULL, 0); //hook the isr handler for LEDC interrupt - * @endcode - * - * ----------------EXAMPLE OF INTERRUPT HANDLER --------------- - * @code{c} - * #include "esp_attr.h" - * void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function - * { - * uint32_t intr_st = LEDC.int_st.val; //read LEDC interrupt status. - * - * //you will find which channels have triggered fade_end interrupt here, - * //then, you can post some event to RTOS queue to process the event. - * //later we will add a queue in the driver code. - * - * LEDC.int_clr.val = intr_st; //clear LEDC interrupt status. - * } - * @endcode - * - *--------------------------END OF EXAMPLE -------------------------- + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_STATE Fade function not installed. + * - ESP_ERR_INVALID_ARG Parameter error. */ - - - +esp_err_t ledc_fade_start(ledc_channel_t channel, ledc_fade_mode_t wait_done); #ifdef __cplusplus } diff --git a/tools/sdk/include/driver/driver/periph_ctrl.h b/tools/sdk/include/driver/driver/periph_ctrl.h index 8c404e5b..0aab5508 100644 --- a/tools/sdk/include/driver/driver/periph_ctrl.h +++ b/tools/sdk/include/driver/driver/periph_ctrl.h @@ -41,6 +41,9 @@ typedef enum { PERIPH_UHCI1_MODULE, PERIPH_RMT_MODULE, PERIPH_PCNT_MODULE, + PERIPH_SPI_MODULE, + PERIPH_HSPI_MODULE, + PERIPH_VSPI_MODULE, } periph_module_t; /** diff --git a/tools/sdk/include/driver/driver/sdmmc_defs.h b/tools/sdk/include/driver/driver/sdmmc_defs.h new file mode 100644 index 00000000..9913bfd1 --- /dev/null +++ b/tools/sdk/include/driver/driver/sdmmc_defs.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2006 Uwe Stuehler + * Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SDMMC_DEFS_H_ +#define _SDMMC_DEFS_H_ + +#include +#include + +/* MMC commands */ /* response type */ +#define MMC_GO_IDLE_STATE 0 /* R0 */ +#define MMC_SEND_OP_COND 1 /* R3 */ +#define MMC_ALL_SEND_CID 2 /* R2 */ +#define MMC_SET_RELATIVE_ADDR 3 /* R1 */ +#define MMC_SWITCH 6 /* R1B */ +#define MMC_SELECT_CARD 7 /* R1 */ +#define MMC_SEND_EXT_CSD 8 /* R1 */ +#define MMC_SEND_CSD 9 /* R2 */ +#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_SET_BLOCK_COUNT 23 /* R1 */ +#define MMC_WRITE_BLOCK_SINGLE 24 /* R1 */ +#define MMC_WRITE_BLOCK_MULTIPLE 25 /* R1 */ +#define MMC_APP_CMD 55 /* R1 */ + +/* SD commands */ /* response type */ +#define SD_SEND_RELATIVE_ADDR 3 /* R6 */ +#define SD_SEND_SWITCH_FUNC 6 /* R1 */ +#define SD_SEND_IF_COND 8 /* R7 */ + +/* SD application commands */ /* response type */ +#define SD_APP_SET_BUS_WIDTH 6 /* R1 */ +#define SD_APP_OP_COND 41 /* R3 */ +#define SD_APP_SEND_SCR 51 /* R1 */ + +/* OCR bits */ +#define MMC_OCR_MEM_READY (1<<31) /* memory power-up status bit */ +#define MMC_OCR_ACCESS_MODE_MASK 0x60000000 /* bits 30:29 */ +#define MMC_OCR_SECTOR_MODE (1<<30) +#define MMC_OCR_BYTE_MODE (1<<29) +#define MMC_OCR_3_5V_3_6V (1<<23) +#define MMC_OCR_3_4V_3_5V (1<<22) +#define MMC_OCR_3_3V_3_4V (1<<21) +#define MMC_OCR_3_2V_3_3V (1<<20) +#define MMC_OCR_3_1V_3_2V (1<<19) +#define MMC_OCR_3_0V_3_1V (1<<18) +#define MMC_OCR_2_9V_3_0V (1<<17) +#define MMC_OCR_2_8V_2_9V (1<<16) +#define MMC_OCR_2_7V_2_8V (1<<15) +#define MMC_OCR_2_6V_2_7V (1<<14) +#define MMC_OCR_2_5V_2_6V (1<<13) +#define MMC_OCR_2_4V_2_5V (1<<12) +#define MMC_OCR_2_3V_2_4V (1<<11) +#define MMC_OCR_2_2V_2_3V (1<<10) +#define MMC_OCR_2_1V_2_2V (1<<9) +#define MMC_OCR_2_0V_2_1V (1<<8) +#define MMC_OCR_1_65V_1_95V (1<<7) + +#define SD_OCR_SDHC_CAP (1<<30) +#define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */ + +/* 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 */ + +/* 48-bit response decoding (32 bits w/o CRC) */ +#define MMC_R1(resp) ((resp)[0]) +#define MMC_R3(resp) ((resp)[0]) +#define SD_R6(resp) ((resp)[0]) +#define MMC_R1_CURRENT_STATE(resp) (((resp)[0] >> 9) & 0xf) + +/* RCA argument and response */ +#define MMC_ARG_RCA(rca) ((rca) << 16) +#define SD_R6_RCA(resp) (SD_R6((resp)) >> 16) + +/* bus width argument */ +#define SD_ARG_BUS_WIDTH_1 0 +#define SD_ARG_BUS_WIDTH_4 2 + +/* EXT_CSD fields */ +#define EXT_CSD_BUS_WIDTH 183 /* WO */ +#define EXT_CSD_HS_TIMING 185 /* R/W */ +#define EXT_CSD_REV 192 /* RO */ +#define EXT_CSD_STRUCTURE 194 /* RO */ +#define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_SEC_COUNT 212 /* RO */ + +/* EXT_CSD field definitions */ +#define EXT_CSD_CMD_SET_NORMAL (1U << 0) +#define EXT_CSD_CMD_SET_SECURE (1U << 1) +#define EXT_CSD_CMD_SET_CPSECURE (1U << 2) + +/* EXT_CSD_HS_TIMING */ +#define EXT_CSD_HS_TIMING_BC 0 +#define EXT_CSD_HS_TIMING_HS 1 +#define EXT_CSD_HS_TIMING_HS200 2 +#define EXT_CSD_HS_TIMING_HS400 3 + +/* EXT_CSD_BUS_WIDTH */ +#define EXT_CSD_BUS_WIDTH_1 0 +#define EXT_CSD_BUS_WIDTH_4 1 +#define EXT_CSD_BUS_WIDTH_8 2 +#define EXT_CSD_BUS_WIDTH_4_DDR 5 +#define EXT_CSD_BUS_WIDTH_8_DDR 6 + +/* 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_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 + +/* 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 */ +#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in value */ +#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ + +/* MMC R2 response (CSD) */ +#define MMC_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2) +#define MMC_CSD_CSDVER_1_0 1 +#define MMC_CSD_CSDVER_2_0 2 +#define MMC_CSD_CSDVER_EXT_CSD 3 +#define MMC_CSD_MMCVER(resp) MMC_RSP_BITS((resp), 122, 4) +#define MMC_CSD_MMCVER_1_0 0 /* MMC 1.0 - 1.2 */ +#define MMC_CSD_MMCVER_1_4 1 /* MMC 1.4 */ +#define MMC_CSD_MMCVER_2_0 2 /* MMC 2.0 - 2.2 */ +#define MMC_CSD_MMCVER_3_1 3 /* MMC 3.1 - 3.3 */ +#define MMC_CSD_MMCVER_4_0 4 /* MMC 4 */ +#define MMC_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4) +#define MMC_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12) +#define MMC_CSD_CAPACITY(resp) ((MMC_CSD_C_SIZE((resp))+1) << \ + (MMC_CSD_C_SIZE_MULT((resp))+2)) +#define MMC_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3) + +/* MMC v1 R2 response (CID) */ +#define MMC_CID_MID_V1(resp) MMC_RSP_BITS((resp), 104, 24) +#define MMC_CID_PNM_V1_CPY(resp, pnm) \ + do { \ + (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ + (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ + (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ + (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ + (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ + (pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \ + (pnm)[6] = MMC_RSP_BITS((resp), 48, 8); \ + (pnm)[7] = '\0'; \ + } while (0) +#define MMC_CID_REV_V1(resp) MMC_RSP_BITS((resp), 40, 8) +#define MMC_CID_PSN_V1(resp) MMC_RSP_BITS((resp), 16, 24) +#define MMC_CID_MDT_V1(resp) MMC_RSP_BITS((resp), 8, 8) + +/* MMC v2 R2 response (CID) */ +#define MMC_CID_MID_V2(resp) MMC_RSP_BITS((resp), 120, 8) +#define MMC_CID_OID_V2(resp) MMC_RSP_BITS((resp), 104, 16) +#define MMC_CID_PNM_V2_CPY(resp, pnm) \ + do { \ + (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ + (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ + (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ + (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ + (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ + (pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \ + (pnm)[6] = '\0'; \ + } while (0) +#define MMC_CID_PSN_V2(resp) MMC_RSP_BITS((resp), 16, 32) + +/* SD R2 response (CSD) */ +#define SD_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2) +#define SD_CSD_CSDVER_1_0 0 +#define SD_CSD_CSDVER_2_0 1 +#define SD_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8) +#define SD_CSD_TAAC_1_5_MSEC 0x26 +#define SD_CSD_NSAC(resp) MMC_RSP_BITS((resp), 104, 8) +#define SD_CSD_SPEED(resp) MMC_RSP_BITS((resp), 96, 8) +#define SD_CSD_SPEED_25_MHZ 0x32 +#define SD_CSD_SPEED_50_MHZ 0x5a +#define SD_CSD_CCC(resp) MMC_RSP_BITS((resp), 84, 12) +#define SD_CSD_CCC_BASIC (1 << 0) /* basic */ +#define SD_CSD_CCC_BR (1 << 2) /* block read */ +#define SD_CSD_CCC_BW (1 << 4) /* block write */ +#define SD_CSD_CCC_ERASE (1 << 5) /* erase */ +#define SD_CSD_CCC_WP (1 << 6) /* write protection */ +#define SD_CSD_CCC_LC (1 << 7) /* lock card */ +#define SD_CSD_CCC_AS (1 << 8) /*application specific*/ +#define SD_CSD_CCC_IOM (1 << 9) /* I/O mode */ +#define SD_CSD_CCC_SWITCH (1 << 10) /* switch */ +#define SD_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4) +#define SD_CSD_READ_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 79, 1) +#define SD_CSD_WRITE_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 78, 1) +#define SD_CSD_READ_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 77, 1) +#define SD_CSD_DSR_IMP(resp) MMC_RSP_BITS((resp), 76, 1) +#define SD_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12) +#define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp))+1) << \ + (SD_CSD_C_SIZE_MULT((resp))+2)) +#define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22) +#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << 10) +#define SD_CSD_V2_BL_LEN 0x9 /* 512 */ +#define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3) +#define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3) +#define SD_CSD_VDD_W_CURR_MIN(resp) MMC_RSP_BITS((resp), 53, 3) +#define SD_CSD_VDD_W_CURR_MAX(resp) MMC_RSP_BITS((resp), 50, 3) +#define SD_CSD_VDD_RW_CURR_100mA 0x7 +#define SD_CSD_VDD_RW_CURR_80mA 0x6 +#define SD_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3) +#define SD_CSD_ERASE_BLK_EN(resp) MMC_RSP_BITS((resp), 46, 1) +#define SD_CSD_SECTOR_SIZE(resp) MMC_RSP_BITS((resp), 39, 7) /* +1 */ +#define SD_CSD_WP_GRP_SIZE(resp) MMC_RSP_BITS((resp), 32, 7) /* +1 */ +#define SD_CSD_WP_GRP_ENABLE(resp) MMC_RSP_BITS((resp), 31, 1) +#define SD_CSD_R2W_FACTOR(resp) MMC_RSP_BITS((resp), 26, 3) +#define SD_CSD_WRITE_BL_LEN(resp) MMC_RSP_BITS((resp), 22, 4) +#define SD_CSD_RW_BL_LEN_2G 0xa +#define SD_CSD_RW_BL_LEN_1G 0x9 +#define SD_CSD_WRITE_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 21, 1) +#define SD_CSD_FILE_FORMAT_GRP(resp) MMC_RSP_BITS((resp), 15, 1) +#define SD_CSD_COPY(resp) MMC_RSP_BITS((resp), 14, 1) +#define SD_CSD_PERM_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 13, 1) +#define SD_CSD_TMP_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 12, 1) +#define SD_CSD_FILE_FORMAT(resp) MMC_RSP_BITS((resp), 10, 2) + +/* SD R2 response (CID) */ +#define SD_CID_MID(resp) MMC_RSP_BITS((resp), 120, 8) +#define SD_CID_OID(resp) MMC_RSP_BITS((resp), 104, 16) +#define SD_CID_PNM_CPY(resp, pnm) \ + do { \ + (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ + (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ + (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ + (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ + (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ + (pnm)[5] = '\0'; \ + } while (0) +#define SD_CID_REV(resp) MMC_RSP_BITS((resp), 56, 8) +#define SD_CID_PSN(resp) MMC_RSP_BITS((resp), 24, 32) +#define SD_CID_MDT(resp) MMC_RSP_BITS((resp), 8, 12) + +/* SCR (SD Configuration Register) */ +#define SCR_STRUCTURE(scr) MMC_RSP_BITS((scr), 60, 4) +#define SCR_STRUCTURE_VER_1_0 0 /* Version 1.0 */ +#define SCR_SD_SPEC(scr) MMC_RSP_BITS((scr), 56, 4) +#define SCR_SD_SPEC_VER_1_0 0 /* Version 1.0 and 1.01 */ +#define SCR_SD_SPEC_VER_1_10 1 /* Version 1.10 */ +#define SCR_SD_SPEC_VER_2 2 /* Version 2.00 or Version 3.0X */ +#define SCR_DATA_STAT_AFTER_ERASE(scr) MMC_RSP_BITS((scr), 55, 1) +#define SCR_SD_SECURITY(scr) MMC_RSP_BITS((scr), 52, 3) +#define SCR_SD_SECURITY_NONE 0 /* no security */ +#define SCR_SD_SECURITY_1_0 1 /* security protocol 1.0 */ +#define SCR_SD_SECURITY_1_0_2 2 /* security protocol 1.0 */ +#define SCR_SD_BUS_WIDTHS(scr) MMC_RSP_BITS((scr), 48, 4) +#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */ +#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */ +#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1) +#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4) +#define SCR_SD_SPEC4(scr) MMC_RSP_BITS((scr), 42, 1) +#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 8) +#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1) +#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1) +#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32) + +/* Status of Switch Function */ +#define SFUNC_STATUS_GROUP(status, group) \ + (__bitfield((uint32_t *)(status), 400 + (group - 1) * 16, 16)) + +#define SD_ACCESS_MODE_SDR12 0 +#define SD_ACCESS_MODE_SDR25 1 +#define SD_ACCESS_MODE_SDR50 2 +#define SD_ACCESS_MODE_SDR104 3 +#define SD_ACCESS_MODE_DDR50 4 + +static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len) +{ + uint32_t mask = (len % 32 == 0) ? UINT_MAX : UINT_MAX >> (32 - (len % 32)); + size_t word = 3 - start / 32; + size_t shift = start % 32; + uint32_t right = src[word] >> shift; + uint32_t left = (len + shift <= 32) ? 0 : src[word - 1] << ((32 - shift) % 32); + return (left | right) & mask; +} + +#endif //_SDMMC_DEFS_H_ diff --git a/tools/sdk/include/driver/driver/sdmmc_host.h b/tools/sdk/include/driver/driver/sdmmc_host.h new file mode 100644 index 00000000..0f56c266 --- /dev/null +++ b/tools/sdk/include/driver/driver/sdmmc_host.h @@ -0,0 +1,165 @@ +// 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. + +#pragma once + +#include +#include +#include "esp_err.h" +#include "sdmmc_types.h" +#include "driver/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SDMMC_HOST_SLOT_0 0 ///< SDMMC slot 0 +#define SDMMC_HOST_SLOT_1 1 ///< SDMMC slot 1 + +/** + * @brief Default sdmmc_host_t structure initializer for SDMMC peripheral + * + * Uses SDMMC peripheral, with 4-bit mode enabled, and max frequency set to 20MHz + */ +#define SDMMC_HOST_DEFAULT() {\ + .flags = SDMMC_HOST_FLAG_4BIT, \ + .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, \ + .set_card_clk = &sdmmc_host_set_card_clk, \ + .do_transaction = &sdmmc_host_do_transaction, \ + .deinit = &sdmmc_host_deinit, \ +} + +/** + * Extra configuration for SDMMC peripheral slot + */ +typedef struct { + gpio_num_t gpio_cd; ///< GPIO number of card detect signal + gpio_num_t gpio_wp; ///< GPIO number of write protect signal +} sdmmc_slot_config_t; + +#define SDMMC_SLOT_NO_CD ((gpio_num_t) -1) ///< indicates that card detect line is not used +#define SDMMC_SLOT_NO_WP ((gpio_num_t) -1) ///< indicates that write protect line is not used + +/** + * Macro defining default configuration of SDMMC host slot + */ +#define SDMMC_SLOT_CONFIG_DEFAULT() {\ + .gpio_cd = SDMMC_SLOT_NO_CD, \ + .gpio_wp = SDMMC_SLOT_NO_WP, \ +} + +/** + * @brief Initialize SDMMC host peripheral + * + * @note This function is not thread safe + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if sdmmc_host_init was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + */ +esp_err_t sdmmc_host_init(); + +/** + * @brief Initialize given slot of SDMMC peripheral + * + * On the ESP32, SDMMC peripheral has two slots: + * - Slot 0: 8-bit wide, maps to HS1_* signals in PIN MUX + * - Slot 1: 4-bit wide, maps to HS2_* signals in PIN MUX + * + * Card detect and write protect signals can be routed to + * arbitrary GPIOs using GPIO matrix. + * + * @note This function is not thread safe + * + * @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param slot_config additional configuration for the slot + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if host has not been initialized using sdmmc_host_init + */ +esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config); + +/** + * @brief Select bus width to be used for data transfer + * + * SD/MMC card must be initialized prior to this command, and a command to set + * bus width has to be sent to the card (e.g. SD_APP_SET_BUS_WIDTH) + * + * @note This function is not thread safe + * + * @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param width bus width (1, 4, or 8 for slot 0; 1 or 4 for slot 1) + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if slot number or width is not valid + */ +esp_err_t sdmmc_host_set_bus_width(int slot, size_t width); + +/** + * @brief Set card clock frequency + * + * Currently only integer fractions of 40MHz clock can be used. + * For High Speed cards, 40MHz can be used. + * For Default Speed cards, 20MHz can be used. + * + * @note This function is not thread safe + * + * @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param freq_khz card clock frequency, in kHz + * @return + * - ESP_OK on success + * - other error codes may be returned in the future + */ +esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz); + +/** + * @brief Send command to the card and get response + * + * This function returns when command is sent and response is received, + * or data is transferred, or timeout occurs. + * + * @note This function is not thread safe w.r.t. init/deinit functions, + * and bus width/clock speed configuration functions. Multiple tasks + * can call sdmmc_host_do_transaction as long as other sdmmc_host_* + * functions are not called. + * + * @param slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param cmdinfo pointer to structure describing command and data to transfer + * @return + * - ESP_OK on success + * - ESP_ERR_TIMEOUT if response or data transfer has timed out + * - ESP_ERR_INVALID_CRC if response or data transfer CRC check has failed + * - ESP_ERR_INVALID_RESPONSE if the card has sent an invalid response + */ +esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo); + +/** + * @brief Disable SDMMC host and release allocated resources + * + * @note This function is not thread safe + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if sdmmc_host_init function has not been called + */ +esp_err_t sdmmc_host_deinit(); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/include/driver/driver/sdmmc_types.h b/tools/sdk/include/driver/driver/sdmmc_types.h new file mode 100644 index 00000000..dfbd2439 --- /dev/null +++ b/tools/sdk/include/driver/driver/sdmmc_types.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2006 Uwe Stuehler + * Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SDMMC_TYPES_H_ +#define _SDMMC_TYPES_H_ + +#include +#include +#include "esp_err.h" + +/** + * Decoded values from SD card Card Specific Data register + */ +typedef struct { + int csd_ver; /*!< CSD structure format */ + int mmc_ver; /*!< MMC version (for CID format) */ + int capacity; /*!< total number of sectors */ + int sector_size; /*!< sector size in bytes */ + int read_block_len; /*!< block length for reads */ + int card_command_class; /*!< Card Command Class for SD */ + int tr_speed; /*!< Max transfer speed */ +} sdmmc_csd_t; + +/** + * Decoded values from SD card Card IDentification register + */ +typedef struct { + int mfg_id; /*!< manufacturer identification number */ + int oem_id; /*!< OEM/product identification number */ + char name[8]; /*!< product name (MMC v1 has the longest) */ + int revision; /*!< product revision */ + int serial; /*!< product serial number */ + int date; /*!< manufacturing date */ +} sdmmc_cid_t; + +/** + * Decoded values from SD Configuration Register + */ +typedef struct { + int sd_spec; /*!< SD Physical layer specification version, reported by card */ + int bus_width; /*!< bus widths supported by card: BIT(0) — 1-bit bus, BIT(2) — 4-bit bus */ +} sdmmc_scr_t; + +/** + * SD/MMC command response buffer + */ +typedef uint32_t sdmmc_response_t[4]; + +/** + * SD/MMC command information + */ +typedef struct { + uint32_t opcode; /*!< SD or MMC command index */ + uint32_t arg; /*!< SD/MMC command argument */ + sdmmc_response_t response; /*!< response buffer */ + void* data; /*!< buffer to send or read into */ + size_t datalen; /*!< length of data buffer */ + size_t blklen; /*!< block length */ + int flags; /*!< see below */ +#define SCF_ITSDONE 0x0001 /*!< command is complete */ +#define SCF_CMD(flags) ((flags) & 0x00f0) +#define SCF_CMD_AC 0x0000 +#define SCF_CMD_ADTC 0x0010 +#define SCF_CMD_BC 0x0020 +#define SCF_CMD_BCR 0x0030 +#define SCF_CMD_READ 0x0040 /*!< read command (data expected) */ +#define SCF_RSP_BSY 0x0100 +#define SCF_RSP_136 0x0200 +#define SCF_RSP_CRC 0x0400 +#define SCF_RSP_IDX 0x0800 +#define SCF_RSP_PRESENT 0x1000 +/* response types */ +#define SCF_RSP_R0 0 /*!< none */ +#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) +#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) +#define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136) +#define SCF_RSP_R3 (SCF_RSP_PRESENT) +#define SCF_RSP_R4 (SCF_RSP_PRESENT) +#define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) +#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) + esp_err_t error; /*!< error returned from transfer */ +} sdmmc_command_t; + +/** + * SD/MMC Host description + * + * This structure defines properties of SD/MMC host and functions + * of SD/MMC host which can be used by upper layers. + */ +typedef struct { + uint32_t flags; /*!< flags defining host properties */ +#define SDMMC_HOST_FLAG_1BIT BIT(0) /*!< host supports 1-line SD and MMC protocol */ +#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 */ + 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 4000 /*!< SD/MMC probing 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 */ + 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 */ +} sdmmc_host_t; + +/** + * SD/MMC card information structure + */ +typedef struct { + sdmmc_host_t host; /*!< Host with which the card is associated */ + uint32_t ocr; /*!< OCR (Operation Conditions Register) value */ + 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 */ + uint16_t rca; /*!< RCA (Relative Card Address) */ +} sdmmc_card_t; + + + + +#endif // _SDMMC_TYPES_H_ diff --git a/tools/sdk/include/driver/driver/spi_master.h b/tools/sdk/include/driver/driver/spi_master.h new file mode 100644 index 00000000..83110d9d --- /dev/null +++ b/tools/sdk/include/driver/driver/spi_master.h @@ -0,0 +1,235 @@ +// 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. + + +#ifndef _DRIVER_SPI_MASTER_H_ +#define _DRIVER_SPI_MASTER_H_ + +#include "esp_err.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * @brief Enum with the three SPI peripherals that are software-accessible in it + */ +typedef enum { + SPI_HOST=0, ///< SPI1, SPI + HSPI_HOST=1, ///< SPI2, HSPI + VSPI_HOST=2 ///< SPI3, VSPI +} spi_host_device_t; + + +/** + * @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 + * the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds. + */ +typedef struct { + int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used. + int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used. + int sclk_io_num; ///< GPIO pin for Spi CLocK signal, or -1 if not used. + int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal which is used as D2 in 4-bit communication modes, or -1 if not used. + int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used. +} spi_bus_config_t; + + +#define SPI_DEVICE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first +#define SPI_DEVICE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first +#define SPI_DEVICE_BIT_LSBFIRST (SPI_TXBIT_LSBFIRST|SPI_RXBIT_LSBFIRST); ///< Transmit and receive LSB first +#define SPI_DEVICE_3WIRE (1<<2) ///< Use spiq for both sending and receiving data +#define SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative +#define SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously +#define SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active + + +typedef struct spi_transaction_t spi_transaction_t; +typedef void(*transaction_cb_t)(spi_transaction_t *trans); + +/** + * @brief This is a configuration for a SPI slave device that is connected to one of the SPI buses. + */ +typedef struct { + uint8_t command_bits; ///< Amount of bits in command phase (0-16) + uint8_t address_bits; ///< Amount of bits in address phase (0-64) + uint8_t dummy_bits; ///< Amount of dummy bits to insert between address and data phase + uint8_t mode; ///< SPI mode (0-3) + uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. + uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions. + uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16) + int clock_speed_hz; ///< Clock speed, in Hz + int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used + uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags + int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time + transaction_cb_t pre_cb; ///< Callback to be called before a transmission is started. This callback is called within interrupt context. + transaction_cb_t post_cb; ///< Callback to be called after a transmission has completed. This callback is called within interrupt context. +} spi_device_interface_config_t; + + +#define SPI_TRANS_MODE_DIO (1<<0) ///< Transmit/receive data in 2-bit mode +#define SPI_TRANS_MODE_QIO (1<<1) ///< Transmit/receive data in 4-bit mode +#define SPI_TRANS_MODE_DIOQIO_ADDR (1<<2) ///< Also transmit address in mode selected by SPI_MODE_DIO/SPI_MODE_QIO +#define SPI_TRANS_USE_RXDATA (1<<2) ///< Receive into rx_data member of spi_transaction_t instead into memory at rx_buffer. +#define SPI_TRANS_USE_TXDATA (1<<3) ///< Transmit tx_data member of spi_transaction_t instead of data at tx_buffer. Do not set tx_buffer when using this. + +/** + * This structure describes one SPI transaction + */ +struct spi_transaction_t { + uint32_t flags; ///< Bitwise OR of SPI_TRANS_* flags + uint16_t command; ///< Command data. Specific length was given when device was added to the bus. + uint64_t address; ///< Address. Specific length was given when device was added to the bus. + size_t length; ///< Total data length, in bits + size_t rxlength; ///< Total data length received, if different from length. (0 defaults this to the value of ``length``) + void *user; ///< User-defined variable. Can be used to store eg transaction ID. + union { + const void *tx_buffer; ///< Pointer to transmit buffer, or NULL for no MOSI phase + uint8_t tx_data[4]; ///< If SPI_USE_TXDATA is set, data set here is sent directly from this variable. + }; + union { + void *rx_buffer; ///< Pointer to receive buffer, or NULL for no MISO phase + uint8_t rx_data[4]; ///< If SPI_USE_RXDATA is set, data is received directly to this variable + }; +}; + + +typedef struct spi_device_t* spi_device_handle_t; ///< Handle for a device on a SPI bus + +/** + * @brief Initialize a SPI bus + * + * @warning For now, only supports HSPI and VSPI. + * + * @param host SPI peripheral that controls this bus + * @param bus_config Pointer to a spi_bus_config_t struct specifying how the host should be initialized + * @param dma_chan Either 1 or 2. A SPI bus used by this driver must have a DMA channel associated with + * it. The SPI hardware has two DMA channels to share. This parameter indicates which + * one to use. + * @return + * - ESP_ERR_INVALID_ARG if configuration is invalid + * - ESP_ERR_INVALID_STATE if host already is in use + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t spi_bus_initialize(spi_host_device_t host, spi_bus_config_t *bus_config, int dma_chan); + +/** + * @brief Free a SPI bus + * + * @warning In order for this to succeed, all devices have to be removed first. + * + * @param host SPI peripheral to free + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_INVALID_STATE if not all devices on the bus are freed + * - ESP_OK on success + */ +esp_err_t spi_bus_free(spi_host_device_t host); + +/** + * @brief Allocate a device on a SPI bus + * + * This initializes the internal structures for a device, plus allocates a CS pin on the indicated SPI master + * peripheral and routes it to the indicated GPIO. All SPI master devices have three CS pins and can thus control + * up to three devices. + * + * @param host SPI peripheral to allocate device on + * @param dev_config SPI interface protocol config for the device + * @param handle Pointer to variable to hold the device handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NOT_FOUND if host doesn't have any free CS slots + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t spi_bus_add_device(spi_host_device_t host, spi_device_interface_config_t *dev_config, spi_device_handle_t *handle); + + +/** + * @brief Remove a device from the SPI bus + * + * @param handle Device handle to free + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_INVALID_STATE if device already is freed + * - ESP_OK on success + */ +esp_err_t spi_bus_remove_device(spi_device_handle_t handle); + + +/** + * @brief Queue a SPI transaction for execution + * + * @param handle Device handle obtained using spi_host_add_dev + * @param trans_desc Description of transaction to execute + * @param ticks_to_wait Ticks to wait until there's room in the queue; use portMAX_DELAY to + * never time out. + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success + */ +esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait); + + +/** + * @brief Get the result of a SPI transaction queued earlier + * + * This routine will wait until a transaction to the given device (queued earlier with + * spi_device_queue_trans) has succesfully completed. It will then return the description of the + * completed transaction so software can inspect the result and e.g. free the memory or + * re-use the buffers. + * + * @param handle Device handle obtained using spi_host_add_dev + * @param trans_desc Pointer to variable able to contain a pointer to the description of the + * transaction that is executed + * @param ticks_to_wait Ticks to wait until there's a returned item; use portMAX_DELAY to never time + out. + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success + */ +esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait); + + +/** + * @brief Do a SPI transaction + * + * Essentially does the same as spi_device_queue_trans followed by spi_device_get_trans_result. Do + * not use this when there is still a transaction queued that hasn't been finalized + * using spi_device_get_trans_result. + * + * @param handle Device handle obtained using spi_host_add_dev + * @param trans_desc Pointer to variable able to contain a pointer to the description of the + * transaction that is executed + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success + */ +esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc); + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tools/sdk/include/esp32/esp_attr.h b/tools/sdk/include/esp32/esp_attr.h index 7ef2920d..911201aa 100644 --- a/tools/sdk/include/esp32/esp_attr.h +++ b/tools/sdk/include/esp32/esp_attr.h @@ -26,7 +26,7 @@ // Forces data into DRAM instead of flash #define DRAM_ATTR __attribute__((section(".dram1"))) -// Forces a string into DRAM instrad of flash +// Forces a string into DRAM instead of flash // Use as ets_printf(DRAM_STR("Hello world!\n")); #define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;})) diff --git a/tools/sdk/include/esp32/esp_core_dump.h b/tools/sdk/include/esp32/esp_core_dump.h new file mode 100644 index 00000000..c6634364 --- /dev/null +++ b/tools/sdk/include/esp32/esp_core_dump.h @@ -0,0 +1,64 @@ +// 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. +#ifndef ESP_CORE_DUMP_H_ +#define ESP_CORE_DUMP_H_ + +/** + * @brief Initializes core dump module internal data. + * + * @note Should be called at system startup. + */ +void esp_core_dump_init(); + +/** + * @brief Saves core dump to flash. + * + * The structure of data stored in flash is as follows: + * | MAGIC1 | + * | TOTAL_LEN | TASKS_NUM | TCB_SIZE | + * | TCB_ADDR_1 | STACK_TOP_1 | STACK_END_1 | TCB_1 | STACK_1 | + * . . . . + * . . . . + * | TCB_ADDR_N | STACK_TOP_N | STACK_END_N | TCB_N | STACK_N | + * | MAGIC2 | + * Core dump in flash consists of header and data for every task in the system at the moment of crash. + * For flash data integrity control two magic numbers are used at the beginning and the end of core dump. + * The structure of core dump data is described below in details. + * 1) MAGIC1 and MAGIC2 are special numbers stored at the beginning and the end of core dump. + * They are used to control core dump data integrity. Size of every number is 4 bytes. + * 2) Core dump starts with header: + * 2.1) TOTAL_LEN is total length of core dump data in flash including magic numbers. Size is 4 bytes. + * 2.2) TASKS_NUM is the number of tasks for which data are stored. Size is 4 bytes. + * 2.3) TCB_SIZE is the size of task's TCB structure. Size is 4 bytes. + * 3) Core dump header is followed by the data for every task in the system. + * Task data are started with task header: + * 3.1) TCB_ADDR is the address of TCB in memory. Size is 4 bytes. + * 3.2) STACK_TOP is the top of task's stack (address of the topmost stack item). Size is 4 bytes. + * 3.2) STACK_END is the end of task's stack (address from which task's stack starts). Size is 4 bytes. + * 4) Task header is followed by TCB data. Size is TCB_SIZE bytes. + * 5) Task's stack is placed after TCB data. Size is (STACK_END - STACK_TOP) bytes. + */ +void esp_core_dump_to_flash(); + +/** + * @brief Print base64-encoded core dump to UART. + * + * The structure of core dump data is the same as for data stored in flash (@see esp_core_dump_to_flash) with some notes: + * 1) Magic numbers are not present in core dump printed to UART. + * 2) Since magic numbers are omitted TOTAL_LEN does not include their size. + * 3) Printed base64 data are surrounded with special messages to help user recognize the start and end of actual data. + */ +void esp_core_dump_to_uart(); + +#endif diff --git a/tools/sdk/include/esp32/esp_err.h b/tools/sdk/include/esp32/esp_err.h index a1f4b8f3..b6a1e8b4 100644 --- a/tools/sdk/include/esp32/esp_err.h +++ b/tools/sdk/include/esp32/esp_err.h @@ -35,7 +35,8 @@ typedef int32_t esp_err_t; #define ESP_ERR_NOT_FOUND 0x105 #define ESP_ERR_NOT_SUPPORTED 0x106 #define ESP_ERR_TIMEOUT 0x107 - +#define ESP_ERR_INVALID_RESPONSE 0x108 +#define ESP_ERR_INVALID_CRC 0x109 #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ diff --git a/tools/sdk/include/esp32/esp_intr_alloc.h b/tools/sdk/include/esp32/esp_intr_alloc.h index c1f91dd2..7195d07d 100644 --- a/tools/sdk/include/esp32/esp_intr_alloc.h +++ b/tools/sdk/include/esp32/esp_intr_alloc.h @@ -124,6 +124,9 @@ esp_err_t esp_intr_reserve(int intno, int cpu); * * The interrupt will always be allocated on the core that runs this function. * + * If ESP_INTR_FLAG_IRAM flag is used, and handler address is not in IRAM or + * RTC_FAST_MEM, then ESP_ERR_INVALID_ARG is returned. + * * @param source The interrupt source. One of the ETS_*_INTR_SOURCE interrupt mux * sources, as defined in soc/soc.h, or one of the internal * ETS_INTERNAL_*_INTR_SOURCE sources as defined in this header. @@ -264,4 +267,4 @@ void esp_intr_noniram_enable(); } #endif -#endif \ No newline at end of file +#endif diff --git a/tools/sdk/include/esp32/esp_panic.h b/tools/sdk/include/esp32/esp_panic.h index 6aba6c5f..aa83c6d3 100644 --- a/tools/sdk/include/esp32/esp_panic.h +++ b/tools/sdk/include/esp32/esp_panic.h @@ -14,8 +14,49 @@ #ifndef __ASSEMBLER__ +#include "esp_err.h" + + +/** + * @brief If an OCD is connected over JTAG. set breakpoint 0 to the given function + * address. Do nothing otherwise. + * @param data Pointer to the target breakpoint position + */ + void esp_set_breakpoint_if_jtag(void *fn); +#define ESP_WATCHPOINT_LOAD 0x40000000 +#define ESP_WATCHPOINT_STORE 0x80000000 +#define ESP_WATCHPOINT_ACCESS 0xC0000000 + +/** + * @brief Set a watchpoint to break/panic when a certain memory range is accessed. + * + * @param no Watchpoint number. On the ESP32, this can be 0 or 1. + * @param adr Base address to watch + * @param size Size of the region, starting at the base address, to watch. Must + * be one of 2^n, with n in [0..6]. + * @param flags One of ESP_WATCHPOINT_* flags + * + * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise + * + * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively + * masking away the lower n bits for a region with size 2^n. If adr does + * not have zero for these lower n bits, you may not be watching the + * region you intended. + */ +esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags); + + +/** + * @brief Clear a watchpoint + * + * @param no Watchpoint to clear + * + */ +void esp_clear_watchpoint(int no); + + #endif -#endif \ No newline at end of file +#endif diff --git a/tools/sdk/include/esp32/esp_phy_init.h b/tools/sdk/include/esp32/esp_phy_init.h index 7bc05361..e669a441 100644 --- a/tools/sdk/include/esp32/esp_phy_init.h +++ b/tools/sdk/include/esp32/esp_phy_init.h @@ -229,7 +229,7 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da * * Applications which don't need to enable PHY on every start up should * disable this menuconfig option and call esp_phy_init before calling - * esp_wifi_init or bt_controller_init. See do_phy_init function in + * esp_wifi_init or esp_bt_controller_init. See do_phy_init function in * cpu_start.c for an example of using this function. * * @param init_data PHY parameters. Default set of parameters can diff --git a/tools/sdk/include/esp32/esp_wifi.h b/tools/sdk/include/esp32/esp_wifi.h index ac49764f..8d4fa17b 100755 --- a/tools/sdk/include/esp32/esp_wifi.h +++ b/tools/sdk/include/esp32/esp_wifi.h @@ -62,6 +62,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "rom/queue.h" +#include "sdkconfig.h" #include "esp_err.h" #include "esp_wifi_types.h" #include "esp_event.h" @@ -76,8 +77,8 @@ extern "C" { #define ESP_ERR_WIFI_ARG ESP_ERR_INVALID_ARG /*!< Invalid argument */ #define ESP_ERR_WIFI_NOT_SUPPORT ESP_ERR_NOT_SUPPORTED /*!< Indicates that API is not supported yet */ -#define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver is not installed by esp_wifi_init */ -#define ESP_ERR_WIFI_NOT_START (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver is not started by esp_wifi_start */ +#define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver was not installed by esp_wifi_init */ +#define ESP_ERR_WIFI_NOT_STARTED (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver was not started by esp_wifi_start */ #define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 3) /*!< WiFi interface error */ #define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 4) /*!< WiFi mode error */ #define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi internal state error */ @@ -85,7 +86,7 @@ extern "C" { #define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal NVS module error */ #define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 8) /*!< MAC address is invalid */ #define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 9) /*!< SSID is invalid */ -#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 10) /*!< Passord is invalid */ +#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 10) /*!< Password is invalid */ #define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 11) /*!< Timeout error */ #define ESP_ERR_WIFI_WAKE_FAIL (ESP_ERR_WIFI_BASE + 12) /*!< WiFi is in sleep state(RF closed) and wakeup fail */ @@ -94,12 +95,17 @@ extern "C" { */ typedef struct { system_event_handler_t event_handler; /**< WiFi event handler */ + uint32_t rx_buf_num; /**< WiFi RX buffer number */ } wifi_init_config_t; - +#ifdef CONFIG_WIFI_ENABLED #define WIFI_INIT_CONFIG_DEFAULT() { \ .event_handler = &esp_event_send, \ + .rx_buf_num = CONFIG_ESP32_WIFI_RX_BUFFER_NUM, \ }; +#else +#define WIFI_INIT_CONFIG_DEFAULT #error Wifi is disabled in config, WIFI_INIT_CONFIG_DEFAULT will not work +#endif /** * @brief Init WiFi @@ -220,8 +226,8 @@ esp_err_t esp_wifi_connect(void); * * @return * - ESP_OK: succeed - * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_INIT: WiFi was not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start * - ESP_ERR_WIFI_FAIL: other WiFi internal errors */ esp_err_t esp_wifi_disconnect(void); @@ -244,7 +250,7 @@ esp_err_t esp_wifi_clear_fast_connect(void); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start * - ESP_ERR_WIFI_ARG: invalid argument * - ESP_ERR_WIFI_MODE: WiFi mode is wrong */ @@ -264,7 +270,7 @@ esp_err_t esp_wifi_deauth_sta(uint16_t aid); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start * - ESP_ERR_WIFI_TIMEOUT: blocking scan is timeout * - others: refer to error code in esp_err.h */ @@ -276,7 +282,7 @@ esp_err_t esp_wifi_scan_start(wifi_scan_config_t *config, bool block); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start */ esp_err_t esp_wifi_scan_stop(void); @@ -290,7 +296,7 @@ esp_err_t esp_wifi_scan_stop(void); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_ARG: invalid argument */ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); @@ -305,7 +311,7 @@ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init - * - ESP_ERR_WIFI_NOT_START: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_ARG: invalid argument * - ESP_ERR_WIFI_NO_MEM: out of memory */ diff --git a/tools/sdk/include/esp32/esp_wifi_types.h b/tools/sdk/include/esp32/esp_wifi_types.h index ac764282..88ad3dcf 100755 --- a/tools/sdk/include/esp32/esp_wifi_types.h +++ b/tools/sdk/include/esp32/esp_wifi_types.h @@ -109,6 +109,8 @@ typedef struct { wifi_second_chan_t second; /**< second channel of AP */ int8_t rssi; /**< signal strength of AP */ wifi_auth_mode_t authmode; /**< authmode of AP */ + uint32_t low_rate_enable:1; /**< bit: 0 flag to identify if low rate is enabled or not */ + uint32_t reserved:31; /**< bit: 1..31 reserved */ } wifi_ap_record_t; typedef enum { @@ -119,9 +121,10 @@ typedef enum { #define WIFI_PROTOCOL_11B 1 #define WIFI_PROTOCOL_11G 2 #define WIFI_PROTOCOL_11N 4 +#define WIFI_PROTOCOL_LR 8 typedef enum { - WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */ + WIFI_BW_HT20 = 1, /* Bandwidth is HT20 */ WIFI_BW_HT40, /* Bandwidth is HT40 */ } wifi_bandwidth_t; diff --git a/tools/sdk/include/esp32/esp_wpa2.h b/tools/sdk/include/esp32/esp_wpa2.h index 1857d19a..e33e0e6d 100644 --- a/tools/sdk/include/esp32/esp_wpa2.h +++ b/tools/sdk/include/esp32/esp_wpa2.h @@ -24,35 +24,58 @@ extern "C" { /** * @brief Enable wpa2 enterprise authentication. * - * @attention wpa2 enterprise authentication can only be used when ESP32 station is enabled. - * wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. * - * @return ESP_ERR_WIFI_OK: succeed. - * ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) + * @return + * - ESP_ERR_WIFI_OK: succeed. + * - ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) */ esp_err_t esp_wifi_sta_wpa2_ent_enable(void); /** * @brief Disable wpa2 enterprise authentication. * - * @attention wpa2 enterprise authentication can only be used when ESP32 station is enabled. - * wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * @attention 1. wpa2 enterprise authentication can only be used when ESP32 station is enabled. + * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. * - * @return ESP_ERR_WIFI_OK: succeed. + * @return + * - ESP_ERR_WIFI_OK: succeed. */ esp_err_t esp_wifi_sta_wpa2_ent_disable(void); +/** + * @brief Set identity for PEAP/TTLS method. + * + * @attention The API only passes the parameter identity to the global pointer variable in wpa2 enterprise module. + * + * @param identity: point to address where stores the identity; + * @param len: length of identity, limited to 1~127 + * + * @return + * - ESP_ERR_WIFI_OK: succeed + * - ESP_ERR_WIFI_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) + */ +esp_err_t esp_wifi_sta_wpa2_ent_set_identity(unsigned char *identity, int len); + +/** + * @brief Clear identity for PEAP/TTLS method. + */ +void esp_wifi_sta_wpa2_ent_clear_identity(void); + /** * @brief Set username for PEAP/TTLS method. * * @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module. * * @param username: point to address where stores the username; - * len: length of username, limited to 1~127 + * @param len: length of username, limited to 1~127 * - * @return ESP_ERR_WIFI_OK: succeed - * ESP_ERR_WIFI_ARG: fail(len <= 0 or len >= 128) - * ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) + * @return + * - ESP_ERR_WIFI_OK: succeed + * - ESP_ERR_WIFI_ARG: fail(len <= 0 or len >= 128) + * - ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) */ esp_err_t esp_wifi_sta_wpa2_ent_set_username(unsigned char *username, int len); @@ -67,11 +90,12 @@ void esp_wifi_sta_wpa2_ent_clear_username(void); * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. * * @param password: point to address where stores the password; - * len: length of password(len > 0) + * @param len: length of password(len > 0) * - * @return ESP_ERR_WIFI_OK: succeed - * ESP_ERR_WIFI_ARG: fail(len <= 0) - * ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) + * @return + * - ESP_ERR_WIFI_OK: succeed + * - ESP_ERR_WIFI_ARG: fail(len <= 0) + * - ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) */ esp_err_t esp_wifi_sta_wpa2_ent_set_password(unsigned char *password, int len); @@ -83,15 +107,16 @@ void esp_wifi_sta_wpa2_ent_clear_password(void); /** * @brief Set new password for MSCHAPv2 method.. * - * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. - * The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. + * @attention 1. The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * @attention 2. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. * * @param password: point to address where stores the password; - * len: length of password + * @param len: length of password * - * @return ESP_ERR_WIFI_OK: succeed - * ESP_ERR_WIFI_ARG: fail(len <= 0) - * ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) + * @return + * - ESP_ERR_WIFI_OK: succeed + * - ESP_ERR_WIFI_ARG: fail(len <= 0) + * - ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail) */ esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(unsigned char *password, int len); @@ -104,13 +129,14 @@ void esp_wifi_sta_wpa2_ent_clear_new_password(void); /** * @brief Set CA certificate for PEAP/TTLS method. * - * @attention The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. - * The ca_cert should be zero terminated. + * @attention 1. The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. + * @attention 2. The ca_cert should be zero terminated. * * @param ca_cert: point to address where stores the CA certificate; - * len: length of ca_cert + * @param len: length of ca_cert * - * @return ESP_ERR_WIFI_OK: succeed + * @return + * - ESP_ERR_WIFI_OK: succeed */ esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(unsigned char *ca_cert, int len); @@ -122,17 +148,18 @@ void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); /** * @brief Set client certificate and key. * - * @attention The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. - * The client_cert, private_key and private_key_passwd should be zero terminated. + * @attention 1. The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. + * @attention 2. The client_cert, private_key and private_key_passwd should be zero terminated. * * @param client_cert: point to address where stores the client certificate; - * client_cert_len: length of client certificate; - * private_key: point to address where stores the private key; - * private_key_len: length of private key, limited to 1~2048; - * private_key_password: point to address where stores the private key password; - * private_key_password_len: length of private key password; + * @param client_cert_len: length of client certificate; + * @param private_key: point to address where stores the private key; + * @param private_key_len: length of private key, limited to 1~2048; + * @param private_key_password: point to address where stores the private key password; + * @param private_key_password_len: length of private key password; * - * @return ESP_ERR_WIFI_OK: succeed + * @return + * - ESP_ERR_WIFI_OK: succeed */ esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(unsigned char *client_cert, int client_cert_len, unsigned char *private_key, int private_key_len, unsigned char *private_key_passwd, int private_key_passwd_len); @@ -145,9 +172,10 @@ void esp_wifi_sta_wpa2_ent_clear_cert_key(void); * @brief Set wpa2 enterprise certs time check(disable or not). * * @param true: disable wpa2 enterprise certs time check - * false: enable wpa2 enterprise certs time check + * @param false: enable wpa2 enterprise certs time check * - * @return ESP_OK: succeed + * @return + * - ESP_OK: succeed */ esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); @@ -156,7 +184,8 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); * * @param disable: store disable value * - * @return ESP_OK: succeed + * @return + * - ESP_OK: succeed */ esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); diff --git a/tools/sdk/include/esp32/rom/ets_sys.h b/tools/sdk/include/esp32/rom/ets_sys.h index 69069167..0f972f2c 100644 --- a/tools/sdk/include/esp32/rom/ets_sys.h +++ b/tools/sdk/include/esp32/rom/ets_sys.h @@ -383,6 +383,18 @@ void ets_delay_us(uint32_t us); */ void ets_update_cpu_frequency(uint32_t ticks_per_us); +/** + * @brief Set the real CPU ticks per us to the ets, so that ets_delay_us will be accurate. + * + * @note This function only sets the tick rate for the current CPU. It is located in ROM, + * so the deep sleep stub can use it even if IRAM is not initialized yet. + * + * @param uint32_t ticks_per_us : CPU ticks per us. + * + * @return None + */ +void ets_update_cpu_frequency_rom(uint32_t ticks_per_us); + /** * @brief Get the real CPU ticks per us to the ets. * This function do not return real CPU ticks per us, just the record in ets. It can be used to check with the real CPU frequency. diff --git a/tools/sdk/include/esp32/rom/rtc.h b/tools/sdk/include/esp32/rom/rtc.h index 1ff7f033..9bcd9bd7 100644 --- a/tools/sdk/include/esp32/rom/rtc.h +++ b/tools/sdk/include/esp32/rom/rtc.h @@ -53,16 +53,18 @@ extern "C" { * Rtc store registers usage * RTC_CNTL_STORE0_REG * RTC_CNTL_STORE1_REG - * RTC_CNTL_STORE2_REG - * RTC_CNTL_STORE3_REG - * RTC_CNTL_STORE4_REG Reserved - * RTC_CNTL_STORE5_REG External Xtal Frequency + * RTC_CNTL_STORE2_REG Boot time, low word + * RTC_CNTL_STORE3_REG Boot time, high word + * RTC_CNTL_STORE4_REG External XTAL frequency + * RTC_CNTL_STORE5_REG APB bus frequency * RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY * RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC ************************************************************************************* */ -#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG -#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG +#define RTC_BOOT_TIME_LOW_REG RTC_CNTL_STORE2_REG +#define RTC_BOOT_TIME_HIGH_REG RTC_CNTL_STORE3_REG +#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG +#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG typedef enum { @@ -179,6 +181,9 @@ void set_rtc_memory_crc(void); /** * @brief Software Reset digital core. * + * It is not recommended to use this function in esp-idf, use + * esp_restart() instead. + * * @param None * * @return None @@ -188,6 +193,9 @@ void software_reset(void); /** * @brief Software Reset digital core. * + * It is not recommended to use this function in esp-idf, use + * esp_restart() instead. + * * @param int cpu_no : The CPU to reset, 0 for PRO CPU, 1 for APP CPU. * * @return None diff --git a/tools/sdk/include/esp32/soc/dport_reg.h b/tools/sdk/include/esp32/soc/dport_reg.h index f8434671..ef231e31 100644 --- a/tools/sdk/include/esp32/soc/dport_reg.h +++ b/tools/sdk/include/esp32/soc/dport_reg.h @@ -1035,14 +1035,20 @@ #define DPORT_WIFI_CLK_EN_V 0xFFFFFFFF #define DPORT_WIFI_CLK_EN_S 0 -#define DPORT_WIFI_RST_EN_REG (DR_REG_DPORT_BASE + 0x0D0) -/* DPORT_WIFI_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +#define DPORT_CORE_RST_EN_REG (DR_REG_DPORT_BASE + 0x0D0) +/* DPORT_CORE_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: */ +#define DPROT_RW_BTLP_RST (BIT(10)) +#define DPROT_RW_BTMAC_RST (BIT(9)) +#define DPORT_MACPWR_RST (BIT(8)) +#define DPORT_EMAC_RST (BIT(7)) +#define DPORT_SDIO_HOST_RST (BIT(6)) +#define DPORT_SDIO_RST (BIT(5)) +#define DPORT_BTMAC_RST (BIT(4)) +#define DPORT_BT_RST (BIT(3)) #define DPORT_MAC_RST (BIT(2)) -#define DPORT_WIFI_RST 0xFFFFFFFF -#define DPORT_WIFI_RST_M ((DPORT_WIFI_RST_V)<<(DPORT_WIFI_RST_S)) -#define DPORT_WIFI_RST_V 0xFFFFFFFF -#define DPORT_WIFI_RST_S 0 +#define DPORT_FE_RST (BIT(1)) +#define DPORT_BB_RST (BIT(0)) #define DPORT_BT_LPCK_DIV_INT_REG (DR_REG_DPORT_BASE + 0x0D4) /* DPORT_BTEXTWAKEUP_REQ : R/W ;bitpos:[12] ;default: 1'b0 ; */ diff --git a/tools/sdk/include/esp32/soc/sdmmc_reg.h b/tools/sdk/include/esp32/soc/sdmmc_reg.h new file mode 100644 index 00000000..d1b452d1 --- /dev/null +++ b/tools/sdk/include/esp32/soc/sdmmc_reg.h @@ -0,0 +1,94 @@ +// 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. +#ifndef _SOC_SDMMC_REG_H_ +#define _SOC_SDMMC_REG_H_ +#include "soc.h" + +#define SDMMC_CTRL_REG (DR_REG_SDMMC_BASE + 0x00) +#define SDMMC_PWREN_REG (DR_REG_SDMMC_BASE + 0x04) +#define SDMMC_CLKDIV_REG (DR_REG_SDMMC_BASE + 0x08) +#define SDMMC_CLKSRC_REG (DR_REG_SDMMC_BASE + 0x0c) +#define SDMMC_CLKENA_REG (DR_REG_SDMMC_BASE + 0x10) +#define SDMMC_TMOUT_REG (DR_REG_SDMMC_BASE + 0x14) +#define SDMMC_CTYPE_REG (DR_REG_SDMMC_BASE + 0x18) +#define SDMMC_BLKSIZ_REG (DR_REG_SDMMC_BASE + 0x1c) +#define SDMMC_BYTCNT_REG (DR_REG_SDMMC_BASE + 0x20) +#define SDMMC_INTMASK_REG (DR_REG_SDMMC_BASE + 0x24) +#define SDMMC_CMDARG_REG (DR_REG_SDMMC_BASE + 0x28) +#define SDMMC_CMD_REG (DR_REG_SDMMC_BASE + 0x2c) +#define SDMMC_RESP0_REG (DR_REG_SDMMC_BASE + 0x30) +#define SDMMC_RESP1_REG (DR_REG_SDMMC_BASE + 0x34) +#define SDMMC_RESP2_REG (DR_REG_SDMMC_BASE + 0x38) +#define SDMMC_RESP3_REG (DR_REG_SDMMC_BASE + 0x3c) + +#define SDMMC_MINTSTS_REG (DR_REG_SDMMC_BASE + 0x40) +#define SDMMC_RINTSTS_REG (DR_REG_SDMMC_BASE + 0x44) +#define SDMMC_STATUS_REG (DR_REG_SDMMC_BASE + 0x48) +#define SDMMC_FIFOTH_REG (DR_REG_SDMMC_BASE + 0x4c) +#define SDMMC_CDETECT_REG (DR_REG_SDMMC_BASE + 0x50) +#define SDMMC_WRTPRT_REG (DR_REG_SDMMC_BASE + 0x54) +#define SDMMC_GPIO_REG (DR_REG_SDMMC_BASE + 0x58) +#define SDMMC_TCBCNT_REG (DR_REG_SDMMC_BASE + 0x5c) +#define SDMMC_TBBCNT_REG (DR_REG_SDMMC_BASE + 0x60) +#define SDMMC_DEBNCE_REG (DR_REG_SDMMC_BASE + 0x64) +#define SDMMC_USRID_REG (DR_REG_SDMMC_BASE + 0x68) +#define SDMMC_VERID_REG (DR_REG_SDMMC_BASE + 0x6c) +#define SDMMC_HCON_REG (DR_REG_SDMMC_BASE + 0x70) +#define SDMMC_UHS_REG_REG (DR_REG_SDMMC_BASE + 0x74) +#define SDMMC_RST_N_REG (DR_REG_SDMMC_BASE + 0x78) +#define SDMMC_BMOD_REG (DR_REG_SDMMC_BASE + 0x80) +#define SDMMC_PLDMND_REG (DR_REG_SDMMC_BASE + 0x84) +#define SDMMC_DBADDR_REG (DR_REG_SDMMC_BASE + 0x88) +#define SDMMC_DBADDRU_REG (DR_REG_SDMMC_BASE + 0x8c) +#define SDMMC_IDSTS_REG (DR_REG_SDMMC_BASE + 0x8c) +#define SDMMC_IDINTEN_REG (DR_REG_SDMMC_BASE + 0x90) +#define SDMMC_DSCADDR_REG (DR_REG_SDMMC_BASE + 0x94) +#define SDMMC_DSCADDRL_REG (DR_REG_SDMMC_BASE + 0x98) +#define SDMMC_DSCADDRU_REG (DR_REG_SDMMC_BASE + 0x9c) +#define SDMMC_BUFADDRL_REG (DR_REG_SDMMC_BASE + 0xa0) +#define SDMMC_BUFADDRU_REG (DR_REG_SDMMC_BASE + 0xa4) +#define SDMMC_CARDTHRCTL_REG (DR_REG_SDMMC_BASE + 0x100) +#define SDMMC_BACK_END_POWER_REG (DR_REG_SDMMC_BASE + 0x104) +#define SDMMC_UHS_REG_EXT_REG (DR_REG_SDMMC_BASE + 0x108) +#define SDMMC_EMMC_DDR_REG_REG (DR_REG_SDMMC_BASE + 0x10c) +#define SDMMC_ENABLE_SHIFT_REG (DR_REG_SDMMC_BASE + 0x110) + +#define SDMMC_CLOCK_REG (DR_REG_SDMMC_BASE + 0x800) + +#define SDMMC_INTMASK_EBE BIT(15) +#define SDMMC_INTMASK_ACD BIT(14) +#define SDMMC_INTMASK_SBE BIT(13) +#define SDMMC_INTMASK_HLE BIT(12) +#define SDMMC_INTMASK_FRUN BIT(11) +#define SDMMC_INTMASK_HTO BIT(10) +#define SDMMC_INTMASK_DTO BIT(9) +#define SDMMC_INTMASK_RTO BIT(8) +#define SDMMC_INTMASK_DCRC BIT(7) +#define SDMMC_INTMASK_RCRC BIT(6) +#define SDMMC_INTMASK_RXDR BIT(5) +#define SDMMC_INTMASK_TXDR BIT(4) +#define SDMMC_INTMASK_DATA_OVER BIT(3) +#define SDMMC_INTMASK_CMD_DONE BIT(2) +#define SDMMC_INTMASK_RESP_ERR BIT(1) +#define SDMMC_INTMASK_CD BIT(0) + +#define SDMMC_IDMAC_INTMASK_AI BIT(9) +#define SDMMC_IDMAC_INTMASK_NI BIT(8) +#define SDMMC_IDMAC_INTMASK_CES BIT(5) +#define SDMMC_IDMAC_INTMASK_DU BIT(4) +#define SDMMC_IDMAC_INTMASK_FBE BIT(2) +#define SDMMC_IDMAC_INTMASK_RI BIT(1) +#define SDMMC_IDMAC_INTMASK_TI BIT(0) + +#endif /* _SOC_SDMMC_REG_H_ */ diff --git a/tools/sdk/include/esp32/soc/sdmmc_struct.h b/tools/sdk/include/esp32/soc/sdmmc_struct.h new file mode 100644 index 00000000..20bb9d26 --- /dev/null +++ b/tools/sdk/include/esp32/soc/sdmmc_struct.h @@ -0,0 +1,371 @@ +// 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. +#ifndef _SOC_SDMMC_STRUCT_H_ +#define _SOC_SDMMC_STRUCT_H_ + +#include + +typedef struct { + uint32_t reserved1: 1; + uint32_t disable_int_on_completion: 1; + uint32_t last_descriptor: 1; + uint32_t first_descriptor: 1; + uint32_t second_address_chained: 1; + uint32_t end_of_ring: 1; + uint32_t reserved2: 24; + uint32_t card_error_summary: 1; + uint32_t owned_by_idmac: 1; + uint32_t buffer1_size: 13; + uint32_t buffer2_size: 13; + uint32_t reserved3: 6; + void* buffer1_ptr; + union { + void* buffer2_ptr; + void* next_desc_ptr; + }; +} sdmmc_desc_t; + +#define SDMMC_DMA_MAX_BUF_LEN 4096 + +_Static_assert(sizeof(sdmmc_desc_t) == 16, "invalid size of sdmmc_desc_t structure"); + + +typedef struct { + uint32_t cmd_index: 6; ///< Command index + uint32_t response_expect: 1; ///< set if response is expected + uint32_t response_long: 1; ///< 0: short response expected, 1: long response expected + uint32_t check_response_crc: 1; ///< set if controller should check response CRC + uint32_t data_expected: 1; ///< 0: no data expected, 1: data expected + uint32_t rw: 1; ///< 0: read from card, 1: write to card (don't care if no data expected) + uint32_t stream_mode: 1; ///< 0: block transfer, 1: stream transfer (don't care if no data expected) + uint32_t send_auto_stop: 1; ///< set to send stop at the end of the transfer + uint32_t wait_complete: 1; ///< 0: send command at once, 1: wait for previous command to complete + uint32_t stop_abort_cmd: 1; ///< set if this is a stop or abort command intended to stop current transfer + uint32_t send_init: 1; ///< set to send init sequence (80 clocks of 1) + uint32_t card_num: 5; ///< card number + uint32_t update_clk_reg: 1; ///< 0: normal command, 1: don't send command, just update clock registers + uint32_t read_ceata: 1; ///< set if performing read from CE-ATA device + uint32_t ccs_expected: 1; ///< set if CCS is expected from CE-ATA device + uint32_t enable_boot: 1; ///< set for mandatory boot mode + uint32_t expect_boot_ack: 1; ///< when set along with enable_boot, controller expects boot ack pattern + uint32_t disable_boot: 1; ///< set to terminate boot operation (don't set along with enable_boot) + uint32_t boot_mode: 1; ///< 0: mandatory boot operation, 1: alternate boot operation + uint32_t volt_switch: 1; ///< set to enable voltage switching (for CMD11 only) + uint32_t use_hold_reg: 1; ///< clear to bypass HOLD register + uint32_t reserved: 1; + uint32_t start_command: 1; ///< Start command; once command is sent to the card, bit is cleared. +} sdmmc_hw_cmd_t; ///< command format used in cmd register; this structure is defined to make it easier to build command values + +_Static_assert(sizeof(sdmmc_hw_cmd_t) == 4, "invalid size of sdmmc_cmd_t structure"); + + +typedef volatile struct { + union { + struct { + uint32_t controller_reset: 1; + uint32_t fifo_reset: 1; + uint32_t dma_reset: 1; + uint32_t reserved1: 1; + uint32_t int_enable: 1; + uint32_t dma_enable: 1; + uint32_t read_wait: 1; + uint32_t send_irq_response: 1; + uint32_t abort_read_data: 1; + uint32_t send_ccsd: 1; + uint32_t send_auto_stop_ccsd: 1; + uint32_t ceata_device_interrupt_status: 1; + uint32_t reserved2: 4; + uint32_t card_voltage_a: 4; + uint32_t card_voltage_b: 4; + uint32_t enable_od_pullup: 1; + uint32_t use_internal_dma: 1; + uint32_t reserved3: 6; + }; + uint32_t val; + } ctrl; + + uint32_t pwren; ///< 1: enable power to card, 0: disable power to card + + union { + struct { + uint32_t div0: 8; ///< 0: bypass, 1-255: divide clock by (2*div0). + uint32_t div1: 8; ///< 0: bypass, 1-255: divide clock by (2*div0). + uint32_t div2: 8; ///< 0: bypass, 1-255: divide clock by (2*div0). + uint32_t div3: 8; ///< 0: bypass, 1-255: divide clock by (2*div0). + }; + uint32_t val; + } clkdiv; + + union { + struct { + uint32_t card0: 2; ///< 0-3: select clock divider for card 0 among div0-div3 + uint32_t card1: 2; ///< 0-3: select clock divider for card 1 among div0-div3 + uint32_t reserved: 28; + }; + uint32_t val; + } clksrc; + + union { + struct { + uint32_t cclk_enable: 16; ///< 1: enable clock to card, 0: disable clock + uint32_t cclk_low_power: 16; ///< 1: enable clock gating when card is idle, 0: disable clock gating + }; + uint32_t val; + } clkena; + + union { + struct { + uint32_t response: 8; ///< response timeout, in card output clock cycles + uint32_t data: 24; ///< data read timeout, in card output clock cycles + }; + uint32_t val; + } tmout; + + union { + struct { + uint32_t card_width: 16; ///< one bit for each card: 0: 1-bit mode, 1: 4-bit mode + uint32_t card_width_8: 16; ///< one bit for each card: 0: not 8-bit mode (corresponding card_width bit is used), 1: 8-bit mode (card_width bit is ignored) + }; + uint32_t val; + } ctype; + + uint32_t blksiz: 16; ///< block size, default 0x200 + uint32_t : 16; + + uint32_t bytcnt; ///< number of bytes to be transferred + + union { + struct { + uint32_t cd: 1; ///< Card detect interrupt enable + uint32_t re: 1; ///< Response error interrupt enable + uint32_t cmd_done: 1; ///< Command done interrupt enable + uint32_t dto: 1; ///< Data transfer over interrupt enable + uint32_t txdr: 1; ///< Transmit FIFO data request interrupt enable + uint32_t rxdr: 1; ///< Receive FIFO data request interrupt enable + uint32_t rcrc: 1; ///< Response CRC error interrupt enable + uint32_t dcrc: 1; ///< Data CRC error interrupt enable + uint32_t rto: 1; ///< Response timeout interrupt enable + uint32_t drto: 1; ///< Data read timeout interrupt enable + uint32_t hto: 1; ///< Data starvation-by-host timeout interrupt enable + uint32_t frun: 1; ///< FIFO underrun/overrun error interrupt enable + uint32_t hle: 1; ///< Hardware locked write error interrupt enable + uint32_t sbi_bci: 1; ///< Start bit error / busy clear interrupt enable + uint32_t acd: 1; ///< Auto command done interrupt enable + uint32_t ebe: 1; ///< End bit error / write no CRC interrupt enable + uint32_t sdio: 16; ///< SDIO interrupt enable + }; + uint32_t val; + } intmask; + + uint32_t cmdarg; ///< Command argument to be passed to card + + sdmmc_hw_cmd_t cmd; + + uint32_t resp[4]; ///< Response from card + + union { + struct { + uint32_t cd: 1; ///< Card detect interrupt masked status + uint32_t re: 1; ///< Response error interrupt masked status + uint32_t cmd_done: 1; ///< Command done interrupt masked status + uint32_t dto: 1; ///< Data transfer over interrupt masked status + uint32_t txdr: 1; ///< Transmit FIFO data request interrupt masked status + uint32_t rxdr: 1; ///< Receive FIFO data request interrupt masked status + uint32_t rcrc: 1; ///< Response CRC error interrupt masked status + uint32_t dcrc: 1; ///< Data CRC error interrupt masked status + uint32_t rto: 1; ///< Response timeout interrupt masked status + uint32_t drto: 1; ///< Data read timeout interrupt masked status + uint32_t hto: 1; ///< Data starvation-by-host timeout interrupt masked status + uint32_t frun: 1; ///< FIFO underrun/overrun error interrupt masked status + uint32_t hle: 1; ///< Hardware locked write error interrupt masked status + uint32_t sbi_bci: 1; ///< Start bit error / busy clear interrupt masked status + uint32_t acd: 1; ///< Auto command done interrupt masked status + uint32_t ebe: 1; ///< End bit error / write no CRC interrupt masked status + uint32_t sdio: 16; ///< SDIO interrupt masked status + }; + uint32_t val; + } mintsts; + + union { + struct { + uint32_t cd: 1; ///< Card detect raw interrupt status + uint32_t re: 1; ///< Response error raw interrupt status + uint32_t cmd_done: 1; ///< Command done raw interrupt status + uint32_t dto: 1; ///< Data transfer over raw interrupt status + uint32_t txdr: 1; ///< Transmit FIFO data request raw interrupt status + uint32_t rxdr: 1; ///< Receive FIFO data request raw interrupt status + uint32_t rcrc: 1; ///< Response CRC error raw interrupt status + uint32_t dcrc: 1; ///< Data CRC error raw interrupt status + uint32_t rto: 1; ///< Response timeout raw interrupt status + uint32_t drto: 1; ///< Data read timeout raw interrupt status + uint32_t hto: 1; ///< Data starvation-by-host timeout raw interrupt status + uint32_t frun: 1; ///< FIFO underrun/overrun error raw interrupt status + uint32_t hle: 1; ///< Hardware locked write error raw interrupt status + uint32_t sbi_bci: 1; ///< Start bit error / busy clear raw interrupt status + uint32_t acd: 1; ///< Auto command done raw interrupt status + uint32_t ebe: 1; ///< End bit error / write no CRC raw interrupt status + uint32_t sdio: 16; ///< SDIO raw interrupt status + }; + uint32_t val; + } rintsts; ///< interrupts can be cleared by writing this register + + union { + struct { + uint32_t fifo_rx_watermark: 1; ///< FIFO reached receive watermark level + uint32_t fifo_tx_watermark: 1; ///< FIFO reached transmit watermark level + uint32_t fifo_empty: 1; ///< FIFO is empty + uint32_t fifo_full: 1; ///< FIFO is full + uint32_t cmd_fsm_state: 4; ///< command FSM state + uint32_t data3_status: 1; ///< this bit reads 1 if card is present + uint32_t data_busy: 1; ///< this bit reads 1 if card is busy + uint32_t data_fsm_busy: 1; ///< this bit reads 1 if transmit/receive FSM is busy + uint32_t response_index: 6; ///< index of the previous response + uint32_t fifo_count: 13; ///< number of filled locations in the FIFO + uint32_t dma_ack: 1; ///< DMA acknowledge signal + uint32_t dma_req: 1; ///< DMA request signal + }; + uint32_t val; + } status; + + union { + struct { + uint32_t tx_watermark: 12; ///< FIFO TX watermark level + uint32_t reserved1: 4; + uint32_t rx_watermark: 12; ///< FIFO RX watermark level + uint32_t dw_dma_mts: 3; + uint32_t reserved2: 1; + }; + uint32_t val; + } fifoth; + + union { + struct { + uint32_t cards: 2; ///< bit N reads 1 if card N is present + uint32_t reserved: 30; + }; + uint32_t val; + } cdetect; + + union { + struct { + uint32_t card0: 2; ///< bit N reads 1 if card N is write protected + uint32_t reserved: 30; + }; + uint32_t val; + } wrtprt; + + uint32_t gpio; ///< unused + uint32_t tcbcnt; ///< transferred (to card) byte count + uint32_t tbbcnt; ///< transferred from host to FIFO byte count + + union { + struct { + uint32_t debounce_count: 24; ///< number of host cycles used by debounce filter, typical time should be 5-25ms + uint32_t reserved: 8; + }; + } debnce; + + uint32_t usrid; ///< user ID + uint32_t verid; ///< IP block version + uint32_t hcon; ///< compile-time IP configuration + uint32_t uhs; ///< TBD + + union { + struct { + uint32_t cards: 2; ///< bit N resets card N, active low + uint32_t reserved: 30; + }; + } rst_n; + + uint32_t reserved_7c; + + union { + struct { + uint32_t sw_reset: 1; ///< set to reset DMA controller + uint32_t fb: 1; ///< set if AHB master performs fixed burst transfers + uint32_t dsl: 5; ///< descriptor skip length: number of words to skip between two unchained descriptors + uint32_t enable: 1; ///< set to enable IDMAC + uint32_t pbl: 3; ///< programmable burst length + uint32_t reserved: 21; + }; + uint32_t val; + } bmod; + + uint32_t pldmnd; ///< set any bit to resume IDMAC FSM from suspended state + sdmmc_desc_t* dbaddr; ///< descriptor list base + + union { + struct { + uint32_t ti: 1; ///< transmit interrupt status + uint32_t ri: 1; ///< receive interrupt status + uint32_t fbe: 1; ///< fatal bus error + uint32_t reserved1: 1; + uint32_t du: 1; ///< descriptor unavailable + uint32_t ces: 1; ///< card error summary + uint32_t reserved2: 2; + uint32_t nis: 1; ///< normal interrupt summary + uint32_t fbe_code: 3; ///< code of fatal bus error + uint32_t fsm: 4; ///< DMAC FSM state + uint32_t reserved3: 15; + }; + uint32_t val; + } idsts; + + union { + struct { + uint32_t ti: 1; ///< transmit interrupt enable + uint32_t ri: 1; ///< receive interrupt enable + uint32_t fbe: 1; ///< fatal bus error interrupt enable + uint32_t reserved1: 1; + uint32_t du: 1; ///< descriptor unavailable interrupt enable + uint32_t ces: 1; ///< card error interrupt enable + uint32_t reserved2: 2; + uint32_t ni: 1; ///< normal interrupt interrupt enable + uint32_t ai: 1; ///< abnormal interrupt enable + uint32_t reserved3: 22; + }; + uint32_t val; + } idinten; + + uint32_t dscaddr; ///< current host descriptor address + uint32_t dscaddrl; ///< unused + uint32_t dscaddru; ///< unused + uint32_t bufaddrl; ///< unused + uint32_t bufaddru; ///< unused + uint32_t reserved_a8[22]; + uint32_t cardthrctl; + uint32_t back_end_power; + uint32_t uhs_reg_ext; + uint32_t emmc_ddr_reg; + uint32_t enable_shift; + uint32_t reserved_114[443]; + union { + struct { + uint32_t phase_dout: 3; ///< phase of data output clock (0x0: 0, 0x1: 90, 0x4: 180, 0x6: 270) + uint32_t phase_din: 3; ///< phase of data input clock + uint32_t phase_core: 3; ///< phase of the clock to SDMMC peripheral + uint32_t div_factor_p: 4; ///< controls clock period; it will be (div_factor_p + 1) / 160MHz + uint32_t div_factor_h: 4; ///< controls length of high pulse; it will be (div_factor_h + 1) / 160MHz + uint32_t div_factor_m: 4; ///< should be equal to div_factor_p + }; + uint32_t val; + } clock; +} sdmmc_dev_t; +extern sdmmc_dev_t SDMMC; + +_Static_assert(sizeof(sdmmc_dev_t) == 0x804, "invalid size of sdmmc_dev_t structure"); + + + +#endif //_SOC_SDMMC_STRUCT_H_ diff --git a/tools/sdk/include/esp32/soc/soc.h b/tools/sdk/include/esp32/soc/soc.h index b93bae72..3e0360e2 100755 --- a/tools/sdk/include/esp32/soc/soc.h +++ b/tools/sdk/include/esp32/soc/soc.h @@ -153,11 +153,12 @@ #define DR_REG_FRC_TIMER_BASE 0x3ff47000 #define DR_REG_RTCCNTL_BASE 0x3ff48000 #define DR_REG_RTCIO_BASE 0x3ff48400 -#define DR_REG_SENS_BASE 0x3ff48800 +#define DR_REG_SENS_BASE 0x3ff48800 #define DR_REG_IO_MUX_BASE 0x3ff49000 #define DR_REG_RTCMEM0_BASE 0x3ff61000 #define DR_REG_RTCMEM1_BASE 0x3ff62000 #define DR_REG_RTCMEM2_BASE 0x3ff63000 +#define DR_REG_SYSCON_BASE 0x3ff66000 #define DR_REG_HINF_BASE 0x3ff4B000 #define DR_REG_UHCI1_BASE 0x3ff4C000 #define DR_REG_I2S_BASE 0x3ff4F000 diff --git a/tools/sdk/include/esp32/soc/spi_reg.h b/tools/sdk/include/esp32/soc/spi_reg.h index d1eeedb9..0cc27b89 100644 --- a/tools/sdk/include/esp32/soc/spi_reg.h +++ b/tools/sdk/include/esp32/soc/spi_reg.h @@ -133,12 +133,8 @@ #define SPI_FLASH_PER_S 16 #define SPI_ADDR_REG(i) (REG_SPI_BASE(i) + 0x4) -/* SPI_USR_ADDR_VALUE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: [31:8]:address to slave [7:0]:Reserved.*/ -#define SPI_USR_ADDR_VALUE 0xFFFFFFFF -#define SPI_USR_ADDR_VALUE_M ((SPI_USR_ADDR_VALUE_V)<<(SPI_USR_ADDR_VALUE_S)) -#define SPI_USR_ADDR_VALUE_V 0xFFFFFFFF -#define SPI_USR_ADDR_VALUE_S 0 +//The CSV actually is wrong here. It indicates that the lower 8 bits of this register are reserved. This is not true, +//all 32 bits of SPI_ADDR_REG are usable/used. #define SPI_CTRL_REG(i) (REG_SPI_BASE(i) + 0x8) /* SPI_WR_BIT_ORDER : R/W ;bitpos:[26] ;default: 1'b0 ; */ @@ -601,19 +597,19 @@ #define SPI_CK_IDLE_EDGE_M (BIT(29)) #define SPI_CK_IDLE_EDGE_V 0x1 #define SPI_CK_IDLE_EDGE_S 29 -/* SPI_MASTER_CK_SEL : R/W ;bitpos:[15:11] ;default: 5'b0 ; */ +/* SPI_MASTER_CK_SEL : R/W ;bitpos:[13:11] ;default: 3'b0 ; */ /*description: In the master mode spi cs line is enable as spi clk it is combined with spi_cs0_dis spi_cs1_dis spi_cs2_dis.*/ -#define SPI_MASTER_CK_SEL 0x0000001F +#define SPI_MASTER_CK_SEL 0x00000007 #define SPI_MASTER_CK_SEL_M ((SPI_MASTER_CK_SEL_V)<<(SPI_MASTER_CK_SEL_S)) -#define SPI_MASTER_CK_SEL_V 0x1F +#define SPI_MASTER_CK_SEL_V 0x07 #define SPI_MASTER_CK_SEL_S 11 -/* SPI_MASTER_CS_POL : R/W ;bitpos:[10:6] ;default: 5'b0 ; */ +/* SPI_MASTER_CS_POL : R/W ;bitpos:[8:6] ;default: 3'b0 ; */ /*description: In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_cs ^ spi_master_cs_pol.*/ -#define SPI_MASTER_CS_POL 0x0000001F +#define SPI_MASTER_CS_POL 0x00000007 #define SPI_MASTER_CS_POL_M ((SPI_MASTER_CS_POL_V)<<(SPI_MASTER_CS_POL_S)) -#define SPI_MASTER_CS_POL_V 0x1F +#define SPI_MASTER_CS_POL_V 0x7 #define SPI_MASTER_CS_POL_S 6 /* SPI_CK_DIS : R/W ;bitpos:[5] ;default: 1'b0 ; */ /*description: 1: spi clk out disable 0: spi clk out enable*/ diff --git a/tools/sdk/include/esp32/soc/spi_struct.h b/tools/sdk/include/esp32/soc/spi_struct.h index c7aa29a7..149782ff 100644 --- a/tools/sdk/include/esp32/soc/spi_struct.h +++ b/tools/sdk/include/esp32/soc/spi_struct.h @@ -36,13 +36,7 @@ typedef volatile struct { }; uint32_t val; } cmd; - union { - struct { - uint32_t reserved : 8; - uint32_t usr_addr_value:24; /*[31:8]:address to slave [7:0]:Reserved.*/ - }; - uint32_t val; - } addr; + uint32_t addr; /*addr to slave / from master */ union { struct { uint32_t reserved0: 10; /*reserved*/ @@ -177,9 +171,10 @@ typedef volatile struct { uint32_t cs2_dis: 1; /*SPI CS2 pin enable, 1: disable CS2, 0: spi_cs2 signal is from/to CS2 pin*/ uint32_t reserved3: 2; /*reserved*/ uint32_t ck_dis: 1; /*1: spi clk out disable 0: spi clk out enable*/ - uint32_t master_cs_pol: 5; /*In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_cs ^ spi_master_cs_pol.*/ - uint32_t master_ck_sel: 5; /*In the master mode spi cs line is enable as spi clk it is combined with spi_cs0_dis spi_cs1_dis spi_cs2_dis.*/ - uint32_t reserved16: 13; /*reserved*/ + uint32_t master_cs_pol: 3; /*In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_cs ^ spi_master_cs_pol.*/ + uint32_t reserved9: 2; /*reserved*/ + uint32_t master_ck_sel: 3; /*In the master mode spi cs line is enable as spi clk it is combined with spi_cs0_dis spi_cs1_dis spi_cs2_dis.*/ + uint32_t reserved14: 15; /*reserved*/ uint32_t ck_idle_edge: 1; /*1: spi clk line is high when idle 0: spi clk line is low when idle*/ uint32_t cs_keep_active: 1; /*spi cs line keep low when the bit is set.*/ uint32_t reserved31: 1; /*reserved*/ @@ -193,7 +188,11 @@ typedef volatile struct { uint32_t rd_sta_done: 1; /*The interrupt raw bit for the completion of read-status operation in the slave mode.*/ uint32_t wr_sta_done: 1; /*The interrupt raw bit for the completion of write-status operation in the slave mode.*/ uint32_t trans_done: 1; /*The interrupt raw bit for the completion of any operation in both the master mode and the slave mode.*/ - uint32_t int_en: 5; /*Interrupt enable bits for the below 5 sources*/ + uint32_t rd_buf_inten: 1; /*The interrupt enable bit for the completion of read-buffer operation in the slave mode.*/ + uint32_t wr_buf_inten: 1; /*The interrupt enable bit for the completion of write-buffer operation in the slave mode.*/ + uint32_t rd_sta_inten: 1; /*The interrupt enable bit for the completion of read-status operation in the slave mode.*/ + uint32_t wr_sta_inten: 1; /*The interrupt enable bit for the completion of write-status operation in the slave mode.*/ + uint32_t trans_inten: 1; /*The interrupt enable bit for the completion of any operation in both the master mode and the slave mode.*/ uint32_t cs_i_mode: 2; /*In the slave mode this bits used to synchronize the input spi cs signal and eliminate spi cs jitter.*/ uint32_t reserved12: 5; /*reserved*/ uint32_t last_command: 3; /*In the slave mode it is the value of command.*/ diff --git a/tools/sdk/include/esp32/soc/syscon_reg.h b/tools/sdk/include/esp32/soc/syscon_reg.h new file mode 100644 index 00000000..5012b27e --- /dev/null +++ b/tools/sdk/include/esp32/soc/syscon_reg.h @@ -0,0 +1,294 @@ +// 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. +#ifndef _SOC_SYSCON_REG_H_ +#define _SOC_SYSCON_REG_H_ + +#include "soc.h" +#define SYSCON_SYSCLK_CONF_REG (DR_REG_SYSCON_BASE + 0x0) +/* SYSCON_QUICK_CLK_CHNG : R/W ;bitpos:[13] ;default: 1'b1 ; */ +/*description: */ +#define SYSCON_QUICK_CLK_CHNG (BIT(13)) +#define SYSCON_QUICK_CLK_CHNG_M (BIT(13)) +#define SYSCON_QUICK_CLK_CHNG_V 0x1 +#define SYSCON_QUICK_CLK_CHNG_S 13 +/* SYSCON_RST_TICK_CNT : R/W ;bitpos:[12] ;default: 1'b0 ; */ +/*description: */ +#define SYSCON_RST_TICK_CNT (BIT(12)) +#define SYSCON_RST_TICK_CNT_M (BIT(12)) +#define SYSCON_RST_TICK_CNT_V 0x1 +#define SYSCON_RST_TICK_CNT_S 12 +/* SYSCON_CLK_EN : R/W ;bitpos:[11] ;default: 1'b0 ; */ +/*description: */ +#define SYSCON_CLK_EN (BIT(11)) +#define SYSCON_CLK_EN_M (BIT(11)) +#define SYSCON_CLK_EN_V 0x1 +#define SYSCON_CLK_EN_S 11 +/* SYSCON_CLK_320M_EN : R/W ;bitpos:[10] ;default: 1'b0 ; */ +/*description: */ +#define SYSCON_CLK_320M_EN (BIT(10)) +#define SYSCON_CLK_320M_EN_M (BIT(10)) +#define SYSCON_CLK_320M_EN_V 0x1 +#define SYSCON_CLK_320M_EN_S 10 +/* SYSCON_PRE_DIV_CNT : R/W ;bitpos:[9:0] ;default: 10'h0 ; */ +/*description: */ +#define SYSCON_PRE_DIV_CNT 0x000003FF +#define SYSCON_PRE_DIV_CNT_M ((SYSCON_PRE_DIV_CNT_V)<<(SYSCON_PRE_DIV_CNT_S)) +#define SYSCON_PRE_DIV_CNT_V 0x3FF +#define SYSCON_PRE_DIV_CNT_S 0 + +#define SYSCON_XTAL_TICK_CONF_REG (DR_REG_SYSCON_BASE + 0x4) +/* SYSCON_XTAL_TICK_NUM : R/W ;bitpos:[7:0] ;default: 8'd39 ; */ +/*description: */ +#define SYSCON_XTAL_TICK_NUM 0x000000FF +#define SYSCON_XTAL_TICK_NUM_M ((SYSCON_XTAL_TICK_NUM_V)<<(SYSCON_XTAL_TICK_NUM_S)) +#define SYSCON_XTAL_TICK_NUM_V 0xFF +#define SYSCON_XTAL_TICK_NUM_S 0 + +#define SYSCON_PLL_TICK_CONF_REG (DR_REG_SYSCON_BASE + 0x8) +/* SYSCON_PLL_TICK_NUM : R/W ;bitpos:[7:0] ;default: 8'd79 ; */ +/*description: */ +#define SYSCON_PLL_TICK_NUM 0x000000FF +#define SYSCON_PLL_TICK_NUM_M ((SYSCON_PLL_TICK_NUM_V)<<(SYSCON_PLL_TICK_NUM_S)) +#define SYSCON_PLL_TICK_NUM_V 0xFF +#define SYSCON_PLL_TICK_NUM_S 0 + +#define SYSCON_CK8M_TICK_CONF_REG (DR_REG_SYSCON_BASE + 0xC) +/* SYSCON_CK8M_TICK_NUM : R/W ;bitpos:[7:0] ;default: 8'd11 ; */ +/*description: */ +#define SYSCON_CK8M_TICK_NUM 0x000000FF +#define SYSCON_CK8M_TICK_NUM_M ((SYSCON_CK8M_TICK_NUM_V)<<(SYSCON_CK8M_TICK_NUM_S)) +#define SYSCON_CK8M_TICK_NUM_V 0xFF +#define SYSCON_CK8M_TICK_NUM_S 0 + +#define SYSCON_SARADC_CTRL_REG (DR_REG_SYSCON_BASE + 0x10) +/* SYSCON_SARADC_DATA_TO_I2S : R/W ;bitpos:[26] ;default: 1'b0 ; */ +/*description: 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data + is from GPIO matrix*/ +#define SYSCON_SARADC_DATA_TO_I2S (BIT(26)) +#define SYSCON_SARADC_DATA_TO_I2S_M (BIT(26)) +#define SYSCON_SARADC_DATA_TO_I2S_V 0x1 +#define SYSCON_SARADC_DATA_TO_I2S_S 26 +/* SYSCON_SARADC_DATA_SAR_SEL : R/W ;bitpos:[25] ;default: 1'b0 ; */ +/*description: 1: sar_sel will be coded by the MSB of the 16-bit output data + in this case the resolution should not be larger than 11 bits.*/ +#define SYSCON_SARADC_DATA_SAR_SEL (BIT(25)) +#define SYSCON_SARADC_DATA_SAR_SEL_M (BIT(25)) +#define SYSCON_SARADC_DATA_SAR_SEL_V 0x1 +#define SYSCON_SARADC_DATA_SAR_SEL_S 25 +/* SYSCON_SARADC_SAR2_PATT_P_CLEAR : R/W ;bitpos:[24] ;default: 1'd0 ; */ +/*description: clear the pointer of pattern table for DIG ADC2 CTRL*/ +#define SYSCON_SARADC_SAR2_PATT_P_CLEAR (BIT(24)) +#define SYSCON_SARADC_SAR2_PATT_P_CLEAR_M (BIT(24)) +#define SYSCON_SARADC_SAR2_PATT_P_CLEAR_V 0x1 +#define SYSCON_SARADC_SAR2_PATT_P_CLEAR_S 24 +/* SYSCON_SARADC_SAR1_PATT_P_CLEAR : R/W ;bitpos:[23] ;default: 1'd0 ; */ +/*description: clear the pointer of pattern table for DIG ADC1 CTRL*/ +#define SYSCON_SARADC_SAR1_PATT_P_CLEAR (BIT(23)) +#define SYSCON_SARADC_SAR1_PATT_P_CLEAR_M (BIT(23)) +#define SYSCON_SARADC_SAR1_PATT_P_CLEAR_V 0x1 +#define SYSCON_SARADC_SAR1_PATT_P_CLEAR_S 23 +/* SYSCON_SARADC_SAR2_PATT_LEN : R/W ;bitpos:[22:19] ;default: 4'd15 ; */ +/*description: 0 ~ 15 means length 1 ~ 16*/ +#define SYSCON_SARADC_SAR2_PATT_LEN 0x0000000F +#define SYSCON_SARADC_SAR2_PATT_LEN_M ((SYSCON_SARADC_SAR2_PATT_LEN_V)<<(SYSCON_SARADC_SAR2_PATT_LEN_S)) +#define SYSCON_SARADC_SAR2_PATT_LEN_V 0xF +#define SYSCON_SARADC_SAR2_PATT_LEN_S 19 +/* SYSCON_SARADC_SAR1_PATT_LEN : R/W ;bitpos:[18:15] ;default: 4'd15 ; */ +/*description: 0 ~ 15 means length 1 ~ 16*/ +#define SYSCON_SARADC_SAR1_PATT_LEN 0x0000000F +#define SYSCON_SARADC_SAR1_PATT_LEN_M ((SYSCON_SARADC_SAR1_PATT_LEN_V)<<(SYSCON_SARADC_SAR1_PATT_LEN_S)) +#define SYSCON_SARADC_SAR1_PATT_LEN_V 0xF +#define SYSCON_SARADC_SAR1_PATT_LEN_S 15 +/* SYSCON_SARADC_SAR_CLK_DIV : R/W ;bitpos:[14:7] ;default: 8'd4 ; */ +/*description: SAR clock divider*/ +#define SYSCON_SARADC_SAR_CLK_DIV 0x000000FF +#define SYSCON_SARADC_SAR_CLK_DIV_M ((SYSCON_SARADC_SAR_CLK_DIV_V)<<(SYSCON_SARADC_SAR_CLK_DIV_S)) +#define SYSCON_SARADC_SAR_CLK_DIV_V 0xFF +#define SYSCON_SARADC_SAR_CLK_DIV_S 7 +/* SYSCON_SARADC_SAR_CLK_GATED : R/W ;bitpos:[6] ;default: 1'b1 ; */ +/*description: */ +#define SYSCON_SARADC_SAR_CLK_GATED (BIT(6)) +#define SYSCON_SARADC_SAR_CLK_GATED_M (BIT(6)) +#define SYSCON_SARADC_SAR_CLK_GATED_V 0x1 +#define SYSCON_SARADC_SAR_CLK_GATED_S 6 +/* SYSCON_SARADC_SAR_SEL : R/W ;bitpos:[5] ;default: 1'd0 ; */ +/*description: 0: SAR1 1: SAR2 only work for single SAR mode*/ +#define SYSCON_SARADC_SAR_SEL (BIT(5)) +#define SYSCON_SARADC_SAR_SEL_M (BIT(5)) +#define SYSCON_SARADC_SAR_SEL_V 0x1 +#define SYSCON_SARADC_SAR_SEL_S 5 +/* SYSCON_SARADC_WORK_MODE : R/W ;bitpos:[4:3] ;default: 2'd0 ; */ +/*description: 0: single mode 1: double mode 2: alternate mode*/ +#define SYSCON_SARADC_WORK_MODE 0x00000003 +#define SYSCON_SARADC_WORK_MODE_M ((SYSCON_SARADC_WORK_MODE_V)<<(SYSCON_SARADC_WORK_MODE_S)) +#define SYSCON_SARADC_WORK_MODE_V 0x3 +#define SYSCON_SARADC_WORK_MODE_S 3 +/* SYSCON_SARADC_SAR2_MUX : R/W ;bitpos:[2] ;default: 1'd0 ; */ +/*description: 1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled + by PWDET CTRL*/ +#define SYSCON_SARADC_SAR2_MUX (BIT(2)) +#define SYSCON_SARADC_SAR2_MUX_M (BIT(2)) +#define SYSCON_SARADC_SAR2_MUX_V 0x1 +#define SYSCON_SARADC_SAR2_MUX_S 2 +/* SYSCON_SARADC_START : R/W ;bitpos:[1] ;default: 1'd0 ; */ +/*description: */ +#define SYSCON_SARADC_START (BIT(1)) +#define SYSCON_SARADC_START_M (BIT(1)) +#define SYSCON_SARADC_START_V 0x1 +#define SYSCON_SARADC_START_S 1 +/* SYSCON_SARADC_START_FORCE : R/W ;bitpos:[0] ;default: 1'd0 ; */ +/*description: */ +#define SYSCON_SARADC_START_FORCE (BIT(0)) +#define SYSCON_SARADC_START_FORCE_M (BIT(0)) +#define SYSCON_SARADC_START_FORCE_V 0x1 +#define SYSCON_SARADC_START_FORCE_S 0 + +#define SYSCON_SARADC_CTRL2_REG (DR_REG_SYSCON_BASE + 0x14) +/* SYSCON_SARADC_SAR2_INV : R/W ;bitpos:[10] ;default: 1'd0 ; */ +/*description: 1: data to DIG ADC2 CTRL is inverted otherwise not*/ +#define SYSCON_SARADC_SAR2_INV (BIT(10)) +#define SYSCON_SARADC_SAR2_INV_M (BIT(10)) +#define SYSCON_SARADC_SAR2_INV_V 0x1 +#define SYSCON_SARADC_SAR2_INV_S 10 +/* SYSCON_SARADC_SAR1_INV : R/W ;bitpos:[9] ;default: 1'd0 ; */ +/*description: 1: data to DIG ADC1 CTRL is inverted otherwise not*/ +#define SYSCON_SARADC_SAR1_INV (BIT(9)) +#define SYSCON_SARADC_SAR1_INV_M (BIT(9)) +#define SYSCON_SARADC_SAR1_INV_V 0x1 +#define SYSCON_SARADC_SAR1_INV_S 9 +/* SYSCON_SARADC_MAX_MEAS_NUM : R/W ;bitpos:[8:1] ;default: 8'd255 ; */ +/*description: max conversion number*/ +#define SYSCON_SARADC_MAX_MEAS_NUM 0x000000FF +#define SYSCON_SARADC_MAX_MEAS_NUM_M ((SYSCON_SARADC_MAX_MEAS_NUM_V)<<(SYSCON_SARADC_MAX_MEAS_NUM_S)) +#define SYSCON_SARADC_MAX_MEAS_NUM_V 0xFF +#define SYSCON_SARADC_MAX_MEAS_NUM_S 1 +/* SYSCON_SARADC_MEAS_NUM_LIMIT : R/W ;bitpos:[0] ;default: 1'd0 ; */ +/*description: */ +#define SYSCON_SARADC_MEAS_NUM_LIMIT (BIT(0)) +#define SYSCON_SARADC_MEAS_NUM_LIMIT_M (BIT(0)) +#define SYSCON_SARADC_MEAS_NUM_LIMIT_V 0x1 +#define SYSCON_SARADC_MEAS_NUM_LIMIT_S 0 + +#define SYSCON_SARADC_FSM_REG (DR_REG_SYSCON_BASE + 0x18) +/* SYSCON_SARADC_SAMPLE_CYCLE : R/W ;bitpos:[31:24] ;default: 8'd2 ; */ +/*description: sample cycles*/ +#define SYSCON_SARADC_SAMPLE_CYCLE 0x000000FF +#define SYSCON_SARADC_SAMPLE_CYCLE_M ((SYSCON_SARADC_SAMPLE_CYCLE_V)<<(SYSCON_SARADC_SAMPLE_CYCLE_S)) +#define SYSCON_SARADC_SAMPLE_CYCLE_V 0xFF +#define SYSCON_SARADC_SAMPLE_CYCLE_S 24 +/* SYSCON_SARADC_START_WAIT : R/W ;bitpos:[23:16] ;default: 8'd8 ; */ +/*description: */ +#define SYSCON_SARADC_START_WAIT 0x000000FF +#define SYSCON_SARADC_START_WAIT_M ((SYSCON_SARADC_START_WAIT_V)<<(SYSCON_SARADC_START_WAIT_S)) +#define SYSCON_SARADC_START_WAIT_V 0xFF +#define SYSCON_SARADC_START_WAIT_S 16 +/* SYSCON_SARADC_STANDBY_WAIT : R/W ;bitpos:[15:8] ;default: 8'd255 ; */ +/*description: */ +#define SYSCON_SARADC_STANDBY_WAIT 0x000000FF +#define SYSCON_SARADC_STANDBY_WAIT_M ((SYSCON_SARADC_STANDBY_WAIT_V)<<(SYSCON_SARADC_STANDBY_WAIT_S)) +#define SYSCON_SARADC_STANDBY_WAIT_V 0xFF +#define SYSCON_SARADC_STANDBY_WAIT_S 8 +/* SYSCON_SARADC_RSTB_WAIT : R/W ;bitpos:[7:0] ;default: 8'd8 ; */ +/*description: */ +#define SYSCON_SARADC_RSTB_WAIT 0x000000FF +#define SYSCON_SARADC_RSTB_WAIT_M ((SYSCON_SARADC_RSTB_WAIT_V)<<(SYSCON_SARADC_RSTB_WAIT_S)) +#define SYSCON_SARADC_RSTB_WAIT_V 0xFF +#define SYSCON_SARADC_RSTB_WAIT_S 0 + +#define SYSCON_SARADC_SAR1_PATT_TAB1_REG (DR_REG_SYSCON_BASE + 0x1C) +/* SYSCON_SARADC_SAR1_PATT_TAB1 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: item 0 ~ 3 for pattern table 1 (each item one byte)*/ +#define SYSCON_SARADC_SAR1_PATT_TAB1 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB1_M ((SYSCON_SARADC_SAR1_PATT_TAB1_V)<<(SYSCON_SARADC_SAR1_PATT_TAB1_S)) +#define SYSCON_SARADC_SAR1_PATT_TAB1_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB1_S 0 + +#define SYSCON_SARADC_SAR1_PATT_TAB2_REG (DR_REG_SYSCON_BASE + 0x20) +/* SYSCON_SARADC_SAR1_PATT_TAB2 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 4 ~ 7 for pattern table 1 (each item one byte)*/ +#define SYSCON_SARADC_SAR1_PATT_TAB2 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB2_M ((SYSCON_SARADC_SAR1_PATT_TAB2_V)<<(SYSCON_SARADC_SAR1_PATT_TAB2_S)) +#define SYSCON_SARADC_SAR1_PATT_TAB2_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB2_S 0 + +#define SYSCON_SARADC_SAR1_PATT_TAB3_REG (DR_REG_SYSCON_BASE + 0x24) +/* SYSCON_SARADC_SAR1_PATT_TAB3 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 8 ~ 11 for pattern table 1 (each item one byte)*/ +#define SYSCON_SARADC_SAR1_PATT_TAB3 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB3_M ((SYSCON_SARADC_SAR1_PATT_TAB3_V)<<(SYSCON_SARADC_SAR1_PATT_TAB3_S)) +#define SYSCON_SARADC_SAR1_PATT_TAB3_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB3_S 0 + +#define SYSCON_SARADC_SAR1_PATT_TAB4_REG (DR_REG_SYSCON_BASE + 0x28) +/* SYSCON_SARADC_SAR1_PATT_TAB4 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 12 ~ 15 for pattern table 1 (each item one byte)*/ +#define SYSCON_SARADC_SAR1_PATT_TAB4 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB4_M ((SYSCON_SARADC_SAR1_PATT_TAB4_V)<<(SYSCON_SARADC_SAR1_PATT_TAB4_S)) +#define SYSCON_SARADC_SAR1_PATT_TAB4_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR1_PATT_TAB4_S 0 + +#define SYSCON_SARADC_SAR2_PATT_TAB1_REG (DR_REG_SYSCON_BASE + 0x2C) +/* SYSCON_SARADC_SAR2_PATT_TAB1 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: item 0 ~ 3 for pattern table 2 (each item one byte)*/ +#define SYSCON_SARADC_SAR2_PATT_TAB1 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB1_M ((SYSCON_SARADC_SAR2_PATT_TAB1_V)<<(SYSCON_SARADC_SAR2_PATT_TAB1_S)) +#define SYSCON_SARADC_SAR2_PATT_TAB1_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB1_S 0 + +#define SYSCON_SARADC_SAR2_PATT_TAB2_REG (DR_REG_SYSCON_BASE + 0x30) +/* SYSCON_SARADC_SAR2_PATT_TAB2 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 4 ~ 7 for pattern table 2 (each item one byte)*/ +#define SYSCON_SARADC_SAR2_PATT_TAB2 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB2_M ((SYSCON_SARADC_SAR2_PATT_TAB2_V)<<(SYSCON_SARADC_SAR2_PATT_TAB2_S)) +#define SYSCON_SARADC_SAR2_PATT_TAB2_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB2_S 0 + +#define SYSCON_SARADC_SAR2_PATT_TAB3_REG (DR_REG_SYSCON_BASE + 0x34) +/* SYSCON_SARADC_SAR2_PATT_TAB3 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 8 ~ 11 for pattern table 2 (each item one byte)*/ +#define SYSCON_SARADC_SAR2_PATT_TAB3 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB3_M ((SYSCON_SARADC_SAR2_PATT_TAB3_V)<<(SYSCON_SARADC_SAR2_PATT_TAB3_S)) +#define SYSCON_SARADC_SAR2_PATT_TAB3_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB3_S 0 + +#define SYSCON_SARADC_SAR2_PATT_TAB4_REG (DR_REG_SYSCON_BASE + 0x38) +/* SYSCON_SARADC_SAR2_PATT_TAB4 : R/W ;bitpos:[31:0] ;default: 32'hf0f0f0f ; */ +/*description: Item 12 ~ 15 for pattern table 2 (each item one byte)*/ +#define SYSCON_SARADC_SAR2_PATT_TAB4 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB4_M ((SYSCON_SARADC_SAR2_PATT_TAB4_V)<<(SYSCON_SARADC_SAR2_PATT_TAB4_S)) +#define SYSCON_SARADC_SAR2_PATT_TAB4_V 0xFFFFFFFF +#define SYSCON_SARADC_SAR2_PATT_TAB4_S 0 + +#define SYSCON_APLL_TICK_CONF_REG (DR_REG_SYSCON_BASE + 0x3C) +/* SYSCON_APLL_TICK_NUM : R/W ;bitpos:[7:0] ;default: 8'd99 ; */ +/*description: */ +#define SYSCON_APLL_TICK_NUM 0x000000FF +#define SYSCON_APLL_TICK_NUM_M ((SYSCON_APLL_TICK_NUM_V)<<(SYSCON_APLL_TICK_NUM_S)) +#define SYSCON_APLL_TICK_NUM_V 0xFF +#define SYSCON_APLL_TICK_NUM_S 0 + +#define SYSCON_DATE_REG (DR_REG_SYSCON_BASE + 0x7C) +/* SYSCON_DATE : R/W ;bitpos:[31:0] ;default: 32'h16042000 ; */ +/*description: */ +#define SYSCON_DATE 0xFFFFFFFF +#define SYSCON_DATE_M ((SYSCON_DATE_V)<<(SYSCON_DATE_S)) +#define SYSCON_DATE_V 0xFFFFFFFF +#define SYSCON_DATE_S 0 + + + + +#endif /*_SOC_SYSCON_REG_H_ */ + + diff --git a/tools/sdk/include/esp32/soc/syscon_struct.h b/tools/sdk/include/esp32/soc/syscon_struct.h new file mode 100644 index 00000000..700aeecf --- /dev/null +++ b/tools/sdk/include/esp32/soc/syscon_struct.h @@ -0,0 +1,120 @@ +// 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. +#ifndef _SOC_SYSCON_STRUCT_H_ +#define _SOC_SYSCON_STRUCT_H_ +typedef struct { + union { + struct { + volatile uint32_t pre_div: 10; + volatile uint32_t clk_320m_en: 1; + volatile uint32_t clk_en: 1; + volatile uint32_t rst_tick: 1; + volatile uint32_t quick_clk_chng: 1; + volatile uint32_t reserved14: 18; + }; + volatile uint32_t val; + }clk_conf; + union { + struct { + volatile uint32_t xtal_tick: 8; + volatile uint32_t reserved8: 24; + }; + volatile uint32_t val; + }xtal_tick_conf; + union { + struct { + volatile uint32_t pll_tick: 8; + volatile uint32_t reserved8: 24; + }; + volatile uint32_t val; + }pll_tick_conf; + union { + struct { + volatile uint32_t ck8m_tick: 8; + volatile uint32_t reserved8: 24; + }; + volatile uint32_t val; + }ck8m_tick_conf; + union { + struct { + volatile uint32_t start_force: 1; + volatile uint32_t start: 1; + volatile uint32_t sar2_mux: 1; /*1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL*/ + volatile uint32_t work_mode: 2; /*0: single mode 1: double mode 2: alternate mode*/ + volatile uint32_t sar_sel: 1; /*0: SAR1 1: SAR2 only work for single SAR mode*/ + volatile uint32_t sar_clk_gated: 1; + volatile uint32_t sar_clk_div: 8; /*SAR clock divider*/ + volatile uint32_t sar1_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/ + volatile uint32_t sar2_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/ + volatile uint32_t sar1_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC1 CTRL*/ + volatile uint32_t sar2_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC2 CTRL*/ + volatile uint32_t data_sar_sel: 1; /*1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits.*/ + volatile uint32_t data_to_i2s: 1; /*1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix*/ + volatile uint32_t reserved27: 5; + }; + volatile uint32_t val; + }saradc_ctrl; + union { + struct { + volatile uint32_t meas_num_limit: 1; + volatile uint32_t max_meas_num: 8; /*max conversion number*/ + volatile uint32_t sar1_inv: 1; /*1: data to DIG ADC1 CTRL is inverted otherwise not*/ + volatile uint32_t sar2_inv: 1; /*1: data to DIG ADC2 CTRL is inverted otherwise not*/ + volatile uint32_t reserved11: 21; + }; + volatile uint32_t val; + }saradc_ctrl2; + union { + struct { + volatile uint32_t rstb_wait: 8; + volatile uint32_t standby_wait: 8; + volatile uint32_t start_wait: 8; + volatile uint32_t sample_cycle: 8; /*sample cycles*/ + }; + volatile uint32_t val; + }saradc_fsm; + volatile uint32_t saradc_sar1_patt_tab1; /*item 0 ~ 3 for pattern table 1 (each item one byte)*/ + volatile uint32_t saradc_sar1_patt_tab2; /*Item 4 ~ 7 for pattern table 1 (each item one byte)*/ + volatile uint32_t saradc_sar1_patt_tab3; /*Item 8 ~ 11 for pattern table 1 (each item one byte)*/ + volatile uint32_t saradc_sar1_patt_tab4; /*Item 12 ~ 15 for pattern table 1 (each item one byte)*/ + volatile uint32_t saradc_sar2_patt_tab1; /*item 0 ~ 3 for pattern table 2 (each item one byte)*/ + volatile uint32_t saradc_sar2_patt_tab2; /*Item 4 ~ 7 for pattern table 2 (each item one byte)*/ + volatile uint32_t saradc_sar2_patt_tab3; /*Item 8 ~ 11 for pattern table 2 (each item one byte)*/ + volatile uint32_t saradc_sar2_patt_tab4; /*Item 12 ~ 15 for pattern table 2 (each item one byte)*/ + union { + struct { + volatile uint32_t apll_tick: 8; + volatile uint32_t reserved8: 24; + }; + volatile uint32_t val; + }apll_tick_conf; + volatile uint32_t reserved_40; + volatile uint32_t reserved_44; + volatile uint32_t reserved_48; + volatile uint32_t reserved_4c; + volatile uint32_t reserved_50; + volatile uint32_t reserved_54; + volatile uint32_t reserved_58; + volatile uint32_t reserved_5c; + volatile uint32_t reserved_60; + volatile uint32_t reserved_64; + volatile uint32_t reserved_68; + volatile uint32_t reserved_6c; + volatile uint32_t reserved_70; + volatile uint32_t reserved_74; + volatile uint32_t reserved_78; + volatile uint32_t date; /**/ +} syscon_dev_t; + +#endif /* _SOC_SYSCON_STRUCT_H_ */ diff --git a/tools/sdk/include/ethernet/esp_eth.h b/tools/sdk/include/ethernet/esp_eth.h index 2aae9d20..e36c3ebf 100644 --- a/tools/sdk/include/ethernet/esp_eth.h +++ b/tools/sdk/include/ethernet/esp_eth.h @@ -79,6 +79,7 @@ typedef eth_duplex_mode_t (*eth_phy_get_duplex_mode_func)(void); typedef void (*eth_phy_func)(void); typedef esp_err_t (*eth_tcpip_input_func)(void *buffer, uint16_t len, void *eb); typedef void (*eth_gpio_config_func)(void); +typedef bool (*eth_phy_get_partner_pause_enable_func)(void); /** @@ -95,6 +96,9 @@ typedef struct { eth_phy_get_speed_mode_func phy_get_speed_mode; /*!< phy check init func */ eth_phy_get_duplex_mode_func phy_get_duplex_mode; /*!< phy check init func */ eth_gpio_config_func gpio_config; /*!< gpio config func */ + bool flow_ctrl_enable; /*!< flag of flow ctrl enable */ + eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */ + } eth_config_t; /** diff --git a/tools/sdk/include/fatfs/diskio.h b/tools/sdk/include/fatfs/diskio.h new file mode 100644 index 00000000..7c224809 --- /dev/null +++ b/tools/sdk/include/fatfs/diskio.h @@ -0,0 +1,120 @@ +/*-----------------------------------------------------------------------/ +/ Low level disk interface modlue include file (C)ChaN, 2014 / +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" +#include "sdmmc_cmd.h" +#include "driver/sdmmc_host.h" + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +/* Redefine names of disk IO functions to prevent name collisions */ +#define disk_initialize ff_disk_initialize +#define disk_status ff_disk_status +#define disk_read ff_disk_read +#define disk_write ff_disk_write +#define disk_ioctl ff_disk_ioctl + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + +/** + * Structure of pointers to disk IO driver functions. + * + * See FatFs documentation for details about these functions + */ +typedef struct { + DSTATUS (*init) (BYTE pdrv); /*!< disk initialization function */ + DSTATUS (*status) (BYTE pdrv); /*!< disk status check function */ + DRESULT (*read) (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); /*!< sector read function */ + DRESULT (*write) (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); /*!< sector write function */ + DRESULT (*ioctl) (BYTE pdrv, BYTE cmd, void* buff); /*!< function to get info about disk and do some misc operations */ +} ff_diskio_impl_t; + +/** + * Register diskio driver for given drive number. + * + * When FATFS library calls one of disk_xxx functions for driver number pdrv, + * corresponding function in discio_impl for given pdrv will be called. + * + * @param pdrv drive number + * @param discio_impl pointer to ff_diskio_impl_t structure with diskio functions + */ +void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl); + +/** + * Register SD/MMC diskio driver + * + * @param pdrv drive number + * @param card pointer to sdmmc_card_t structure describing a card; card should be initialized before calling f_mount. + */ +void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card); + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (Used by FatFs) */ +#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ +#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ +#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ + +/* Generic command (Not used by FatFs) */ +#define CTRL_POWER 5 /* Get/Set power status */ +#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ +#define ISDIO_READ 55 /* Read data form SD iSDIO register */ +#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ +#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/include/fatfs/esp_vfs_fat.h b/tools/sdk/include/fatfs/esp_vfs_fat.h new file mode 100644 index 00000000..087d6cf7 --- /dev/null +++ b/tools/sdk/include/fatfs/esp_vfs_fat.h @@ -0,0 +1,107 @@ +// 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. + +#pragma once +#include +#include "esp_err.h" +#include "driver/gpio.h" +#include "driver/sdmmc_types.h" +#include "driver/sdmmc_host.h" +#include "ff.h" + +/** + * @brief Register FATFS with VFS component + * + * This function registers given FAT drive in VFS, at the specified base path. + * If only one drive is used, fat_drive argument can be an empty string. + * Refer to FATFS library documentation on how to specify FAT drive. + * This function also allocates FATFS structure which should be used for f_mount + * call. + * + * @note This function doesn't mount the drive into FATFS, it just connects + * POSIX and C standard library IO function with FATFS. You need to mount + * desired drive into FATFS separately. + * + * @param base_path path prefix where FATFS should be registered + * @param fat_drive FATFS drive specification; if only one drive is used, can be an empty string + * @param max_files maximum number of files which can be open at the same time + * @param[out] out_fs pointer to FATFS structure which can be used for FATFS f_mount call is returned via this argument. + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_register was already called + * - ESP_ERR_NO_MEM if not enough memory or too many VFSes already registered + */ +esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, + size_t max_files, FATFS** out_fs); + +/** + * @brief Un-register FATFS from VFS + * + * @note FATFS structure returned by esp_vfs_fat_register is destroyed after + * this call. Make sure to call f_mount function to unmount it before + * calling esp_vfs_fat_unregister. + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if FATFS is not registered in VFS + */ +esp_err_t esp_vfs_fat_unregister(); + +/** + * @brief Configuration arguments for esp_vfs_fat_sdmmc_mount function + */ +typedef struct { + bool format_if_mount_failed; ///< If FAT partition can not be mounted, and this parameter is true, create partition table and format the filesystem + int max_files; ///< Max number of open files +} esp_vfs_fat_sdmmc_mount_config_t; + +/** + * @brief Convenience function to get FAT filesystem on SD card registered in VFS + * + * This is an all-in-one function which does the following: + * - initializes SD/MMC peripheral with configuration in host_config + * - initializes SD/MMC card with configuration in slot_config + * - mounts FAT partition on SD/MMC card using FATFS library, with configuration in mount_config + * - registers FATFS library with VFS, with prefix given by base_prefix variable + * + * This function is intended to make example code more compact. + * For real world applications, developers should implement the logic of + * probing SD card, locating and mounting partition, and registering FATFS in VFS, + * with proper error checking and handling of exceptional conditions. + * + * @param base_path path where partition should be registered (e.g. "/sdcard") + * @param host_config pointer to structure describing SDMMC host + * @param slot_config pointer to structure with extra SDMMC slot configuration + * @param mount_config pointer to structure with extra parameters for mounting FATFS + * @param[out] out_card if not NULL, pointer to the card information structure will be returned via this argument + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes from SDMMC host, SDMMC protocol, or FATFS drivers + */ +esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path, + const sdmmc_host_t* host_config, + const sdmmc_slot_config_t* slot_config, + const esp_vfs_fat_sdmmc_mount_config_t* mount_config, + sdmmc_card_t** out_card); + +/** + * @brief Unmount FAT filesystem and release resources acquired using esp_vfs_fat_sdmmc_mount + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount hasn't been called + */ +esp_err_t esp_vfs_fat_sdmmc_unmount(); diff --git a/tools/sdk/include/fatfs/ff.h b/tools/sdk/include/fatfs/ff.h new file mode 100644 index 00000000..18bc85b1 --- /dev/null +++ b/tools/sdk/include/fatfs/ff.h @@ -0,0 +1,369 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - Generic FAT file system module R0.12b / +/-----------------------------------------------------------------------------/ +/ +/ Copyright (C) 2016, ChaN, all right reserved. +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: + +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/----------------------------------------------------------------------------*/ + + +#ifndef _FATFS +#define _FATFS 68020 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + +#ifdef FF_DEFINE_DIR +#define FF_DIR DIR +#endif + + +/* Definitions of volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +typedef struct { + BYTE pd; /* Physical drive number */ + BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ +} PARTITION; +extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ +#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ +#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ + +#else /* Single partition configuration */ +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ +#define LD2PT(vol) 0 /* Find first valid partition or in SFD */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode (UTF-16) string */ +#if _USE_LFN == 0 +#error _LFN_UNICODE must be 0 at non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif +#endif + + + +/* Type of file size variables */ + +#if _FS_EXFAT +#if _USE_LFN == 0 +#error LFN must be enabled when enable exFAT +#endif +typedef QWORD FSIZE_t; +#else +typedef DWORD FSIZE_t; +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* File system type (0:N/A) */ + BYTE drv; /* Physical drive number */ + BYTE n_fats; /* Number of FATs (1 or 2) */ + BYTE wflag; /* win[] flag (b0:dirty) */ + BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ + WORD csize; /* Cluster size [sectors] */ +#if _MAX_SS != _MIN_SS + WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ +#endif +#if _USE_LFN != 0 + WCHAR* lfnbuf; /* LFN working buffer */ +#endif +#if _FS_EXFAT + BYTE* dirbuf; /* Directory entry block scratchpad buffer */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clst; /* Last allocated cluster */ + DWORD free_clst; /* Number of free clusters */ +#endif +#if _FS_RPATH != 0 + DWORD cdir; /* Current directory start cluster (0:root) */ +#if _FS_EXFAT + DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ + DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ + DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ +#endif +#endif + DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ + DWORD fsize; /* Size of an FAT [sectors] */ + DWORD volbase; /* Volume base sector */ + DWORD fatbase; /* FAT base sector */ + DWORD dirbase; /* Root directory base sector/cluster */ + DWORD database; /* Data base sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ +} FATFS; + + + +/* Object ID and allocation information (_FDID) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE attr; /* Object attribute */ + BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */ + DWORD sclust; /* Object start cluster (0:no cluster or root directory) */ + FSIZE_t objsize; /* Object size (valid when sclust != 0) */ +#if _FS_EXFAT + DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */ + DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ + DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ + DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */ +#endif +#if _FS_LOCK != 0 + UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ +#endif +} _FDID; + + + +/* File object structure (FIL) */ + +typedef struct { + _FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ + BYTE flag; /* File status flags */ + BYTE err; /* Abort flag (error code) */ + FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ + DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */ + DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector number containing the directory entry */ + BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File private data read/write window */ +#endif +} FIL; + + + +/* Directory object structure (FF_DIR) */ + +typedef struct { + _FDID obj; /* Object identifier */ + DWORD dptr; /* Current read/write offset */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the directory item in the win[] */ + BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ +#if _USE_LFN != 0 + DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ +#endif +#if _USE_FIND + const TCHAR* pat; /* Pointer to the name matching pattern */ +#endif +} FF_DIR; + + + +/* File information structure (FILINFO) */ + +typedef struct { + FSIZE_t fsize; /* File size */ + WORD fdate; /* Modified date */ + WORD ftime; /* Modified time */ + BYTE fattrib; /* File attribute */ +#if _USE_LFN != 0 + TCHAR altname[13]; /* Altenative file name */ + TCHAR fname[_MAX_LFN + 1]; /* Primary file name */ +#else + TCHAR fname[13]; /* File name */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ + FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_close (FIL* fp); /* Close an open file object */ +FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ +FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ +FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ +FRESULT f_truncate (FIL* fp); /* Truncate the file */ +FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ +FRESULT f_opendir (FF_DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_closedir (FF_DIR* dp); /* Close an open directory */ +FRESULT f_readdir (FF_DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_findfirst (FF_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ +FRESULT f_findnext (FF_DIR* dp, FILINFO* fno); /* Find next file */ +FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ +FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ +FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ +FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ +FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ +FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ +FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ +FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ +FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ +FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ +int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ +int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ +int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ + +#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) +#define f_error(fp) ((fp)->err) +#define f_tell(fp) ((fp)->fptr) +#define f_size(fp) ((fp)->obj.objsize) +#define f_rewind(fp) f_lseek((fp), 0) +#define f_rewinddir(dp) f_readdir((dp), 0) + +#ifndef EOF +#define EOF (-1) +#endif + + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY && !_FS_NORTC +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN != 0 /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT msize); /* Allocate memory block */ +void ff_memfree (void* mblock); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access mode and open method flags (3rd argument of f_open) */ +#define FA_READ 0x01 +#define FA_WRITE 0x02 +#define FA_OPEN_EXISTING 0x00 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA_OPEN_APPEND 0x30 + +/* Fast seek controls (2nd argument of f_lseek) */ +#define CREATE_LINKMAP ((FSIZE_t)0 - 1) + +/* Format options (2nd argument of f_mkfs) */ +#define FM_FAT 0x01 +#define FM_FAT32 0x02 +#define FM_EXFAT 0x04 +#define FM_ANY 0x07 +#define FM_SFD 0x08 + +/* Filesystem type (FATFS.fs_type) */ +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 +#define FS_EXFAT 4 + +/* File attribute bits for directory entry (FILINFO.fattrib) */ +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/tools/sdk/include/fatfs/ffconf.h b/tools/sdk/include/fatfs/ffconf.h new file mode 100644 index 00000000..23b63ea9 --- /dev/null +++ b/tools/sdk/include/fatfs/ffconf.h @@ -0,0 +1,267 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file +/---------------------------------------------------------------------------*/ + +#define _FFCONF 68020 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define _FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: All basic functions are enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define _USE_STRFUNC 0 +/* This option switches string functions, f_gets(), f_putc(), f_puts() and +/ f_printf(). +/ +/ 0: Disable string functions. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. */ + + +#define _USE_FIND 0 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define _USE_MKFS 1 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + + +#define _USE_FASTSEEK 0 +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + + +#define _USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define _USE_CHMOD 0 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */ + + +#define _USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define _USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1 +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 1 - ASCII (No extended character. Non-LFN cfg. only) +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +*/ + + +#define _USE_LFN 0 +#define _MAX_LFN 255 +/* The _USE_LFN switches the support of long file name (LFN). +/ +/ 0: Disable support of LFN. _MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added +/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and +/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255. +/ It should be set 255 to support full featured LFN operations. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree(), must be added to the project. */ + + +#define _LFN_UNICODE 0 +/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) +/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. +/ This option also affects behavior of string I/O functions. */ + + +#define _STRF_ENCODE 3 +/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to +/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). +/ +/ 0: ANSI/OEM +/ 1: UTF-16LE +/ 2: UTF-16BE +/ 3: UTF-8 +/ +/ This option has no effect when _LFN_UNICODE == 0. */ + + +#define _FS_RPATH 0 +/* This option configures support of relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define _VOLUMES 2 +/* Number of volumes (logical drives) to be used. */ + + +#define _STR_VOLUME_ID 0 +#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +/* _STR_VOLUME_ID switches string support of volume ID. +/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive +/ number in the path name. _VOLUME_STRS defines the drive ID strings for each +/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for +/ the drive ID strings are: A-Z and 0-9. */ + + +#define _MULTI_PARTITION 1 +/* This option switches support of multi-partition on a physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When multi-partition is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + + +#define _MIN_SS 512 +#define _MAX_SS 512 +/* These options configure the range of sector size to be supported. (512, 1024, +/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and +/ harddisk. But a larger value may be required for on-board flash memory and some +/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured +/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the +/ disk_ioctl() function. */ + + +#define _USE_TRIM 0 +/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + +#define _FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_TINY 0 +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the file system object (FATFS) is used for the file data transfer. */ + + +#define _FS_EXFAT 0 +/* This option switches support of exFAT file system. (0:Disable or 1:Enable) +/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1) +/ Note that enabling exFAT discards C89 compatibility. */ + + +#define _FS_NORTC 0 +#define _NORTC_MON 1 +#define _NORTC_MDAY 1 +#define _NORTC_YEAR 2016 +/* The option _FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable +/ the timestamp function. All objects modified by FatFs will have a fixed timestamp +/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time. +/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to get current time form real-time clock. _NORTC_MON, +/ _NORTC_MDAY and _NORTC_YEAR have no effect. +/ These options have no effect at read-only configuration (_FS_READONLY = 1). */ + + +#define _FS_LOCK 0 +/* The option _FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when _FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +#define _FS_REENTRANT 1 +#define _FS_TIMEOUT 1000 +#define _SYNC_t SemaphoreHandle_t +/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The _FS_TIMEOUT defines timeout period in unit of time tick. +/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.h. */ + +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +/*--- End of configuration options ---*/ diff --git a/tools/sdk/include/fatfs/integer.h b/tools/sdk/include/fatfs/integer.h new file mode 100644 index 00000000..4660ed62 --- /dev/null +++ b/tools/sdk/include/fatfs/integer.h @@ -0,0 +1,38 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _FF_INTEGER +#define _FF_INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include +typedef unsigned __int64 QWORD; + + +#else /* Embedded platform */ + +/* These types MUST be 16-bit or 32-bit */ +typedef int INT; +typedef unsigned int UINT; + +/* This type MUST be 8-bit */ +typedef unsigned char BYTE; + +/* These types MUST be 16-bit */ +typedef short SHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types MUST be 32-bit */ +typedef long LONG; +typedef unsigned long DWORD; + +/* This type MUST be 64-bit (Remove this for C89 compatibility) */ +typedef unsigned long long QWORD; + +#endif + +#endif diff --git a/tools/sdk/include/freertos/freertos/FreeRTOS.h b/tools/sdk/include/freertos/freertos/FreeRTOS.h index 4c60308f..0e93acf2 100644 --- a/tools/sdk/include/freertos/freertos/FreeRTOS.h +++ b/tools/sdk/include/freertos/freertos/FreeRTOS.h @@ -863,8 +863,8 @@ typedef struct xSTATIC_TCB void *pxDummy6; uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; UBaseType_t uxDummyCoreId; - #if ( portSTACK_GROWTH > 0 ) - void *pxDummy8; + #if ( portSTACK_GROWTH > 0 || configENABLE_TASK_SNAPSHOT == 1 ) + void *pxDummy8; #endif #if ( portCRITICAL_NESTING_IN_TCB == 1 ) UBaseType_t uxDummy9; diff --git a/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h b/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h index 4f101265..b2fc077b 100644 --- a/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h +++ b/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h @@ -268,7 +268,9 @@ #define configXT_BOARD 1 /* Board mode */ #define configXT_SIMULATOR 0 - +#if CONFIG_ESP32_ENABLE_COREDUMP +#define configENABLE_TASK_SNAPSHOT 1 +#endif #endif /* FREERTOS_CONFIG_H */ diff --git a/tools/sdk/include/freertos/freertos/portable.h b/tools/sdk/include/freertos/freertos/portable.h index 9ed378a8..b05755da 100644 --- a/tools/sdk/include/freertos/freertos/portable.h +++ b/tools/sdk/include/freertos/freertos/portable.h @@ -187,6 +187,13 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; void vPortYieldOtherCore( BaseType_t coreid) PRIVILEGED_FUNCTION; + +/* + Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack + watchpoint around. + */ +void vPortSetStackWatchpoint( void* pxStackStart ); + /* * The structures and methods of manipulating the MPU are contained within the * port layer. diff --git a/tools/sdk/include/freertos/freertos/task.h b/tools/sdk/include/freertos/freertos/task.h index f7b9181f..590b07a2 100644 --- a/tools/sdk/include/freertos/freertos/task.h +++ b/tools/sdk/include/freertos/freertos/task.h @@ -181,6 +181,18 @@ typedef struct xTASK_STATUS uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ } TaskStatus_t; +/* + * Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system. + * We need this struct because TCB_t is defined (hidden) in tasks.c. + */ +typedef struct xTASK_SNAPSHOT +{ + void *pxTCB; /* Address of task control block. */ + StackType_t *pxTopOfStack; /* Points to the location of the last item placed on the tasks stack. */ + StackType_t *pxEndOfStack; /* Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo + pxTopOfStack > pxEndOfStack, stack grows lo2hi*/ +} TaskSnapshot_t; + /* Possible return values for eTaskConfirmSleepModeStatus(). */ typedef enum { @@ -2173,6 +2185,17 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; */ void *pvTaskIncrementMutexHeldCount( void ); +/* + * This function fills array with TaskSnapshot_t structures for every task in the system. + * Used by core dump facility to get snapshots of all tasks in the system. + * Only available when configENABLE_TASK_SNAPSHOT is set to 1. + * @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data. + * @param uxArraySize Size of tasks snapshots array. + * @param pxTcbSz Pointer to store size of TCB. + * @return Number of elements stored in array. + */ +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz ); + #ifdef __cplusplus } #endif diff --git a/tools/sdk/include/json/cJSON.h b/tools/sdk/include/json/cJSON.h index 466d10db..92ed8c3b 100644 --- a/tools/sdk/include/json/cJSON.h +++ b/tools/sdk/include/json/cJSON.h @@ -90,6 +90,7 @@ extern cJSON *cJSON_CreateTrue(void); extern cJSON *cJSON_CreateFalse(void); extern cJSON *cJSON_CreateBool(int b); extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateDouble(double num,int i_num); extern cJSON *cJSON_CreateString(const char *string); extern cJSON *cJSON_CreateArray(void); extern cJSON *cJSON_CreateObject(void); diff --git a/tools/sdk/include/log/esp_log.h b/tools/sdk/include/log/esp_log.h index 33bc10b4..6fda8d60 100644 --- a/tools/sdk/include/log/esp_log.h +++ b/tools/sdk/include/log/esp_log.h @@ -75,6 +75,16 @@ void esp_log_set_vprintf(vprintf_like_t func); */ uint32_t esp_log_timestamp(void); +/** + * @brief Function which returns timestamp to be used in log output + * + * This function uses HW cycle counter and does not depend on OS, + * so it can be safely used after application crash. + * + * @return timestamp, in milliseconds + */ +uint32_t esp_log_early_timestamp(void); + /** * @brief Write message into the log * diff --git a/tools/sdk/include/lwip/arpa/inet.h b/tools/sdk/include/lwip/arpa/inet.h new file mode 100644 index 00000000..94c6c17e --- /dev/null +++ b/tools/sdk/include/lwip/arpa/inet.h @@ -0,0 +1,20 @@ +// 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. + +#ifndef INET_H_ +#define INET_H_ + +#include "lwip/inet.h" + +#endif /* INET_H_ */ diff --git a/tools/sdk/include/lwip/lwip/opt.h b/tools/sdk/include/lwip/lwip/opt.h index c42f3cd7..4d8d6bf7 100755 --- a/tools/sdk/include/lwip/lwip/opt.h +++ b/tools/sdk/include/lwip/lwip/opt.h @@ -1665,7 +1665,7 @@ * LWIP_STATS==1: Enable statistics collection in lwip_stats. */ #ifndef LWIP_STATS -#define LWIP_STATS 1 +#define LWIP_STATS 0 #endif #if LWIP_STATS diff --git a/tools/sdk/include/lwip/lwipopts.h b/tools/sdk/include/lwip/lwipopts.h old mode 100755 new mode 100644 index dd182923..6d1dfbd4 --- a/tools/sdk/include/lwip/lwipopts.h +++ b/tools/sdk/include/lwip/lwipopts.h @@ -189,6 +189,10 @@ ---------- RAW options ---------- --------------------------------- */ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#define LWIP_RAW 1 /* ---------------------------------- @@ -402,6 +406,27 @@ */ #define DEFAULT_ACCEPTMBOX_SIZE 6 +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_STACKSIZE TCPIP_THREAD_STACKSIZE + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_PRIO TCPIP_THREAD_PRIO + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_RAW_RECVMBOX_SIZE 6 + /* ---------------------------------------------- ---------- Sequential layer options ---------- @@ -572,21 +597,37 @@ #define ESP_LIGHT_SLEEP 1 #define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY #define ESP_CNT_DEBUG 0 -#define ESP_DUAL_CORE 0 -#define TCP_WND_DEFAULT (4*TCP_MSS) -#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) +#define TCP_WND_DEFAULT (4*TCP_MSS) +#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) + +#if ESP_PERF +#define DBG_PERF_PATH_SET(dir, point) +#define DBG_PERF_FILTER_LEN 1000 + +enum { + DBG_PERF_DIR_RX = 0, + DBG_PERF_DIR_TX, +}; + +enum { + DBG_PERF_POINT_INT = 0, + DBG_PERF_POINT_WIFI_IN = 1, + DBG_PERF_POINT_WIFI_OUT = 2, + DBG_PERF_POINT_LWIP_IN = 3, + DBG_PERF_POINT_LWIP_OUT = 4, + DBG_PERF_POINT_SOC_IN = 5, + DBG_PERF_POINT_SOC_OUT = 6, +}; + +#else +#define DBG_PERF_PATH_SET(dir, point) +#define DBG_PERF_FILTER_LEN 1000 +#endif #if ESP_PER_SOC_TCP_WND -#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) -#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) -#else -#if ESP_PERF -extern unsigned char misc_prof_get_tcpw(void); -extern unsigned char misc_prof_get_tcp_snd_buf(void); -#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS) -#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS) -#endif +#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) +#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) #endif /** @@ -595,6 +636,7 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); #define DHCP_DEBUG LWIP_DBG_OFF #define LWIP_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF +#define ESP_STATS 0 #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_IP 0 diff --git a/tools/sdk/include/lwip/netinet/in.h b/tools/sdk/include/lwip/netinet/in.h new file mode 100644 index 00000000..7eaec633 --- /dev/null +++ b/tools/sdk/include/lwip/netinet/in.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef IN_H_ +#define IN_H_ + +#include "lwip/inet.h" + +#define IN6_IS_ADDR_MULTICAST(a) IN_MULTICAST(a) + +#endif /* IN_H_ */ diff --git a/tools/sdk/include/lwip/port/arpa/inet.h b/tools/sdk/include/lwip/port/arpa/inet.h new file mode 100644 index 00000000..94c6c17e --- /dev/null +++ b/tools/sdk/include/lwip/port/arpa/inet.h @@ -0,0 +1,20 @@ +// 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. + +#ifndef INET_H_ +#define INET_H_ + +#include "lwip/inet.h" + +#endif /* INET_H_ */ diff --git a/tools/sdk/include/lwip/port/lwipopts.h b/tools/sdk/include/lwip/port/lwipopts.h old mode 100755 new mode 100644 index dd182923..6d1dfbd4 --- a/tools/sdk/include/lwip/port/lwipopts.h +++ b/tools/sdk/include/lwip/port/lwipopts.h @@ -189,6 +189,10 @@ ---------- RAW options ---------- --------------------------------- */ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#define LWIP_RAW 1 /* ---------------------------------- @@ -402,6 +406,27 @@ */ #define DEFAULT_ACCEPTMBOX_SIZE 6 +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_STACKSIZE TCPIP_THREAD_STACKSIZE + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_PRIO TCPIP_THREAD_PRIO + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_RAW_RECVMBOX_SIZE 6 + /* ---------------------------------------------- ---------- Sequential layer options ---------- @@ -572,21 +597,37 @@ #define ESP_LIGHT_SLEEP 1 #define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY #define ESP_CNT_DEBUG 0 -#define ESP_DUAL_CORE 0 -#define TCP_WND_DEFAULT (4*TCP_MSS) -#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) +#define TCP_WND_DEFAULT (4*TCP_MSS) +#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) + +#if ESP_PERF +#define DBG_PERF_PATH_SET(dir, point) +#define DBG_PERF_FILTER_LEN 1000 + +enum { + DBG_PERF_DIR_RX = 0, + DBG_PERF_DIR_TX, +}; + +enum { + DBG_PERF_POINT_INT = 0, + DBG_PERF_POINT_WIFI_IN = 1, + DBG_PERF_POINT_WIFI_OUT = 2, + DBG_PERF_POINT_LWIP_IN = 3, + DBG_PERF_POINT_LWIP_OUT = 4, + DBG_PERF_POINT_SOC_IN = 5, + DBG_PERF_POINT_SOC_OUT = 6, +}; + +#else +#define DBG_PERF_PATH_SET(dir, point) +#define DBG_PERF_FILTER_LEN 1000 +#endif #if ESP_PER_SOC_TCP_WND -#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) -#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) -#else -#if ESP_PERF -extern unsigned char misc_prof_get_tcpw(void); -extern unsigned char misc_prof_get_tcp_snd_buf(void); -#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS) -#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS) -#endif +#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) +#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) #endif /** @@ -595,6 +636,7 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); #define DHCP_DEBUG LWIP_DBG_OFF #define LWIP_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF +#define ESP_STATS 0 #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_IP 0 diff --git a/tools/sdk/include/lwip/port/netinet/in.h b/tools/sdk/include/lwip/port/netinet/in.h new file mode 100644 index 00000000..7eaec633 --- /dev/null +++ b/tools/sdk/include/lwip/port/netinet/in.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef IN_H_ +#define IN_H_ + +#include "lwip/inet.h" + +#define IN6_IS_ADDR_MULTICAST(a) IN_MULTICAST(a) + +#endif /* IN_H_ */ diff --git a/tools/sdk/include/mdns/mdns.h b/tools/sdk/include/mdns/mdns.h new file mode 100644 index 00000000..58e588e3 --- /dev/null +++ b/tools/sdk/include/mdns/mdns.h @@ -0,0 +1,235 @@ +// 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. +#ifndef ESP_MDNS_H_ +#define ESP_MDNS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct mdns_server_s; +typedef struct mdns_server_s mdns_server_t; + +/** + * @brief mDNS query result structure + * + */ +typedef struct mdns_result_s { + const char * host; /*!< hostname */ + const char * instance; /*!< instance */ + const char * txt; /*!< txt data */ + uint16_t priority; /*!< service priority */ + uint16_t weight; /*!< service weight */ + uint16_t port; /*!< service port */ + struct ip4_addr addr; /*!< ip4 address */ + struct ip6_addr addrv6; /*!< ip6 address */ + const struct mdns_result_s * next; /*!< next result, or NULL for the last result in the list */ +} mdns_result_t; + +/** + * @brief Initialize mDNS on given interface + * + * @param tcpip_if Interface that the server will listen on + * @param server Server pointer to populate on success + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG when bad tcpip_if is given + * - ESP_ERR_INVALID_STATE when the network returned error + * - ESP_ERR_NO_MEM on memory error + * - ESP_ERR_WIFI_NOT_INIT when WiFi is not initialized by eps_wifi_init + */ +esp_err_t mdns_init(tcpip_adapter_if_t tcpip_if, mdns_server_t ** server); + +/** + * @brief Stop and free mDNS server + * + * @param server mDNS Server to free + * + */ +void mdns_free(mdns_server_t * server); + +/** + * @brief Set the hostname for mDNS server + * + * @param server mDNS Server + * @param hostname Hostname to set + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NO_MEM memory error + */ +esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname); + +/** + * @brief Set the default instance name for mDNS server + * + * @param server mDNS Server + * @param instance Instance name to set + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NO_MEM memory error + */ +esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance); + +/** + * @brief Add service to mDNS server + * + * @param server mDNS Server + * @param service service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * @param port service port + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NO_MEM memory error + */ +esp_err_t mdns_service_add(mdns_server_t * server, const char * service, const char * proto, uint16_t port); + +/** + * @brief Remove service from mDNS server + * + * @param server mDNS Server + * @param service service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NOT_FOUND Service not found + * - ESP_FAIL unknown error + */ +esp_err_t mdns_service_remove(mdns_server_t * server, const char * service, const char * proto); + +/** + * @brief Set instance name for service + * + * @param server mDNS Server + * @param service service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * @param instance instance name to set + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NOT_FOUND Service not found + * - ESP_ERR_NO_MEM memory error + */ +esp_err_t mdns_service_instance_set(mdns_server_t * server, const char * service, const char * proto, const char * instance); + +/** + * @brief Set TXT data for service + * + * @param server mDNS Server + * @param service service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * @param num_items number of items in TXT data + * @param txt string array of TXT data (eg. {"var=val","other=2"}) + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NOT_FOUND Service not found + * - ESP_ERR_NO_MEM memory error + */ +esp_err_t mdns_service_txt_set(mdns_server_t * server, const char * service, const char * proto, uint8_t num_items, const char ** txt); + +/** + * @brief Set service port + * + * @param server mDNS Server + * @param service service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * @param port service port + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NOT_FOUND Service not found + */ +esp_err_t mdns_service_port_set(mdns_server_t * server, const char * service, const char * proto, uint16_t port); + +/** + * @brief Remove and free all services from mDNS server + * + * @param server mDNS Server + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t mdns_service_remove_all(mdns_server_t * server); + +/** + * @brief Query mDNS for host or service + * + * @param server mDNS Server + * @param service service type or host name + * @param proto service protocol or NULL if searching for host + * @param timeout time to wait for answers. If 0, mdns_query_end MUST be called to end the search + * + * @return the number of results found + */ +size_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout); + +/** + * @brief Stop mDNS Query started with timeout = 0 + * + * @param server mDNS Server + * + * @return the number of results found + */ +size_t mdns_query_end(mdns_server_t * server); + +/** + * @brief get the number of results currently in memoty + * + * @param server mDNS Server + * + * @return the number of results + */ +size_t mdns_result_get_count(mdns_server_t * server); + +/** + * @brief Get mDNS Search result with given index + * + * @param server mDNS Server + * @param num the index of the result + * + * @return the result or NULL if error + */ +const mdns_result_t * mdns_result_get(mdns_server_t * server, size_t num); + +/** + * @brief Remove and free all search results from mDNS server + * + * @param server mDNS Server + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t mdns_result_free(mdns_server_t * server); + +#ifdef __cplusplus +} +#endif + +#endif /* ESP_MDNS_H_ */ diff --git a/tools/sdk/include/newlib/esp_newlib.h b/tools/sdk/include/newlib/esp_newlib.h new file mode 100644 index 00000000..eac35442 --- /dev/null +++ b/tools/sdk/include/newlib/esp_newlib.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef __ESP_NEWLIB_H__ +#define __ESP_NEWLIB_H__ + +#include + +/** + * Replacement for newlib's _REENT_INIT_PTR and __sinit. + * + * Called from startup code and FreeRTOS, not intended to be called from + * application code. + */ +void esp_reent_init(struct _reent* r); + +/** + * Function which sets up syscall table used by newlib functions in ROM. + * + * Called from the startup code, not intended to be called from application + * code. + */ +void esp_setup_syscall_table(); + +/** + * Initialize hardware timer used as time source for newlib time functions. + * + * Called from the startup code, not intended to be called from application. + */ +void esp_setup_time_syscalls(); + +#endif //__ESP_NEWLIB_H__ diff --git a/tools/sdk/include/newlib/stdatomic.h b/tools/sdk/include/newlib/stdatomic.h index 09c0cf73..beba325b 100644 --- a/tools/sdk/include/newlib/stdatomic.h +++ b/tools/sdk/include/newlib/stdatomic.h @@ -32,6 +32,7 @@ #include #include +#include #if __has_extension(c_atomic) || __has_extension(cxx_atomic) #define __CLANG_ATOMICS diff --git a/tools/sdk/include/newlib/sys/dirent.h b/tools/sdk/include/newlib/sys/dirent.h deleted file mode 100644 index a3fb5c02..00000000 --- a/tools/sdk/include/newlib/sys/dirent.h +++ /dev/null @@ -1,13 +0,0 @@ -/* includes , which is this file. On a - system which supports , this file is overridden by - dirent.h in the libc/sys/.../sys directory. On a system which does - not support , we will get this file which uses #error to force - an error. */ - -#ifdef __cplusplus -extern "C" { -#endif -#error " not supported" -#ifdef __cplusplus -} -#endif diff --git a/tools/sdk/include/openssl/openssl/ssl.h b/tools/sdk/include/openssl/openssl/ssl.h old mode 100644 new mode 100755 index 7f8eb883..39d4bf73 --- a/tools/sdk/include/openssl/openssl/ssl.h +++ b/tools/sdk/include/openssl/openssl/ssl.h @@ -214,6 +214,14 @@ const SSL_METHOD* TLSv1_1_client_method(void); */ const SSL_METHOD* TLSv1_2_client_method(void); +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context client method + */ +const SSL_METHOD* TLS_client_method(void); /** * @brief create the target SSL context server method @@ -260,6 +268,16 @@ const SSL_METHOD* TLSv1_server_method(void); */ const SSL_METHOD* SSLv3_server_method(void); +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context server method + */ +const SSL_METHOD* TLS_server_method(void); + + /** * @brief set the SSL context ALPN select callback function * diff --git a/tools/sdk/include/sdmmc/sdmmc_cmd.h b/tools/sdk/include/sdmmc/sdmmc_cmd.h new file mode 100644 index 00000000..58b6f082 --- /dev/null +++ b/tools/sdk/include/sdmmc/sdmmc_cmd.h @@ -0,0 +1,77 @@ +// 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. + +#pragma once + +#include +#include "esp_err.h" +#include "driver/sdmmc_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Probe and initialize SD/MMC card using given host + * + * @note Only SD cards (SDSC and SDHC/SDXC) are supported now. + * Support for MMC/eMMC cards will be added later. + * + * @param host pointer to structure defining host controller + * @param out_card pointer to structure which will receive information about the card when the function completes + * @return + * - ESP_OK on success + * - One of the error codes from SDMMC host controller + */ +esp_err_t sdmmc_card_init(const sdmmc_host_t* host, + sdmmc_card_t* out_card); + +/** + * @brief Print information about the card to a stream + * @param stream stream obtained using fopen or fdopen + * @param card card information structure initialized using sdmmc_card_init + */ +void sdmmc_card_print_info(FILE* stream, const sdmmc_card_t* card); + +/** + * Write given number of sectors to SD/MMC card + * + * @param card pointer to card information structure previously initialized using sdmmc_card_init + * @param src pointer to data buffer to read data from; data size must be equal to sector_count * card->csd.sector_size + * @param start_sector sector where to start writing + * @param sector_count number of sectors to write + * @return + * - ESP_OK on success + * - One of the error codes from SDMMC host controller + */ +esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, + size_t start_sector, size_t sector_count); + +/** + * Write given number of sectors to SD/MMC card + * + * @param card pointer to card information structure previously initialized using sdmmc_card_init + * @param dst pointer to data buffer to write into; buffer size must be at least sector_count * card->csd.sector_size + * @param start_sector sector where to start reading + * @param sector_count number of sectors to read + * @return + * - ESP_OK on success + * - One of the error codes from SDMMC host controller + */ +esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst, + size_t start_sector, size_t sector_count); + +#ifdef __cplusplus +} +#endif diff --git a/tools/sdk/include/spi_flash/esp_partition.h b/tools/sdk/include/spi_flash/esp_partition.h index b67891ae..b149e102 100644 --- a/tools/sdk/include/spi_flash/esp_partition.h +++ b/tools/sdk/include/spi_flash/esp_partition.h @@ -69,6 +69,7 @@ typedef enum { ESP_PARTITION_SUBTYPE_DATA_OTA = 0x00, //!< OTA selection partition ESP_PARTITION_SUBTYPE_DATA_PHY = 0x01, //!< PHY init data partition ESP_PARTITION_SUBTYPE_DATA_NVS = 0x02, //!< NVS partition + ESP_PARTITION_SUBTYPE_DATA_COREDUMP = 0x03, //!< COREDUMP partition ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80, //!< ESPHTTPD partition ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81, //!< FAT partition diff --git a/tools/sdk/include/spi_flash/esp_spi_flash.h b/tools/sdk/include/spi_flash/esp_spi_flash.h index bb3ec39b..bf897e89 100644 --- a/tools/sdk/include/spi_flash/esp_spi_flash.h +++ b/tools/sdk/include/spi_flash/esp_spi_flash.h @@ -173,6 +173,49 @@ void spi_flash_munmap(spi_flash_mmap_handle_t handle); */ void spi_flash_mmap_dump(); +/** + * @brief SPI flash critical section enter function. + */ +typedef void (*spi_flash_guard_start_func_t)(void); +/** + * @brief SPI flash critical section exit function. + */ +typedef void (*spi_flash_guard_end_func_t)(void); + +/** + * Structure holding SPI flash access critical section management functions + * + * @note Structure and corresponding guard functions should not reside in flash. + * For example structure can be placed in DRAM and functions in IRAM sections. + */ +typedef struct { + spi_flash_guard_start_func_t start; /**< critical section start func */ + spi_flash_guard_end_func_t end; /**< critical section end func */ +} spi_flash_guard_funcs_t; + +/** + * @brief Sets guard functions to access flash. + * + * @note Pointed structure and corresponding guard functions should not reside in flash. + * For example structure can be placed in DRAM and functions in IRAM sections. + * + * @param funcs pointer to structure holding flash access guard functions. + */ +void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs); + +/** + * @brief Default OS-aware flash access guard functions + */ +extern const spi_flash_guard_funcs_t g_flash_guard_default_ops; + +/** + * @brief Non-OS flash access guard functions + * + * @note This version of flash guard functions is to be used when no OS is present or from panic handler. + * It does not use any OS primitives and IPC and implies that only calling CPU is active. + */ +extern const spi_flash_guard_funcs_t g_flash_guard_no_os_ops; + #if CONFIG_SPI_FLASH_ENABLE_COUNTERS /** diff --git a/tools/sdk/include/tcpip_adapter/tcpip_adapter.h b/tools/sdk/include/tcpip_adapter/tcpip_adapter.h index 861f7ccb..4f3b49ed 100644 --- a/tools/sdk/include/tcpip_adapter/tcpip_adapter.h +++ b/tools/sdk/include/tcpip_adapter/tcpip_adapter.h @@ -58,6 +58,17 @@ extern "C" { #define IPSTR "%d.%d.%d.%d" +#define IPV62STR(ipaddr) IP6_ADDR_BLOCK1(&(ipaddr)), \ + IP6_ADDR_BLOCK2(&(ipaddr)), \ + IP6_ADDR_BLOCK3(&(ipaddr)), \ + IP6_ADDR_BLOCK4(&(ipaddr)), \ + IP6_ADDR_BLOCK5(&(ipaddr)), \ + IP6_ADDR_BLOCK6(&(ipaddr)), \ + IP6_ADDR_BLOCK7(&(ipaddr)), \ + IP6_ADDR_BLOCK8(&(ipaddr)) + +#define IPV6STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" + typedef struct { ip4_addr_t ip; ip4_addr_t netmask; @@ -98,7 +109,7 @@ typedef struct { typedef enum { TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */ TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */ - TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */ + TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */ TCPIP_ADAPTER_IF_MAX } tcpip_adapter_if_t; @@ -126,7 +137,7 @@ typedef enum{ } tcpip_adapter_option_id_t; /** - * @brief Initialize tcpip adpater + * @brief Initialize tcpip adapter * * This will initialize TCPIP stack inside. */ @@ -411,12 +422,12 @@ esp_interface_t tcpip_adapter_get_esp_if(void *dev); */ esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list); -#define TCPIP_HOSTNAME_MAX_SIZE 31 +#define TCPIP_HOSTNAME_MAX_SIZE 32 /** * @brief Set the hostname to the interface * * @param[in] tcpip_if: the interface which we will set the hostname - * @param[in] hostname: the host name for set the interfce + * @param[in] hostname: the host name for set the interface, the max length of hostname is 32 bytes * * @return ESP_OK:success * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error @@ -428,7 +439,7 @@ esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *ho * @brief Get the hostname from the interface * * @param[in] tcpip_if: the interface which we will get the hostname - * @param[in] hostname: the host name from the interfce + * @param[in] hostname: the host name from the interface * * @return ESP_OK:success * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error diff --git a/tools/sdk/include/vfs/esp_vfs.h b/tools/sdk/include/vfs/esp_vfs.h index 7dd273fb..304750aa 100644 --- a/tools/sdk/include/vfs/esp_vfs.h +++ b/tools/sdk/include/vfs/esp_vfs.h @@ -21,6 +21,8 @@ #include #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -106,6 +108,38 @@ typedef struct int (*rename_p)(void* ctx, const char *src, const char *dst); int (*rename)(const char *src, const char *dst); }; + union { + DIR* (*opendir_p)(void* ctx, const char* name); + DIR* (*opendir)(const char* name); + }; + union { + struct dirent* (*readdir_p)(void* ctx, DIR* pdir); + struct dirent* (*readdir)(DIR* pdir); + }; + union { + int (*readdir_r_p)(void* ctx, DIR* pdir, struct dirent* entry, struct dirent** out_dirent); + int (*readdir_r)(DIR* pdir, struct dirent* entry, struct dirent** out_dirent); + }; + union { + long (*telldir_p)(void* ctx, DIR* pdir); + long (*telldir)(DIR* pdir); + }; + union { + void (*seekdir_p)(void* ctx, DIR* pdir, long offset); + void (*seekdir)(DIR* pdir, long offset); + }; + union { + int (*closedir_p)(void* ctx, DIR* pdir); + int (*closedir)(DIR* pdir); + }; + union { + int (*mkdir_p)(void* ctx, const char* name, mode_t mode); + int (*mkdir)(const char* name, mode_t mode); + }; + union { + int (*rmdir_p)(void* ctx, const char* name); + int (*rmdir)(const char* name); + }; } esp_vfs_t; @@ -131,6 +165,15 @@ typedef struct esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ctx); +/** + * Unregister a virtual filesystem for given path prefix + * + * @param base_path file prefix previously used in esp_vfs_register call + * @return ESP_OK if successful, ESP_ERR_INVALID_STATE if VFS for given prefix + * hasn't been registered + */ +esp_err_t esp_vfs_unregister(const char* base_path); + /** * These functions are to be used in newlib syscall table. They will be called by * newlib when it needs to use any of the syscalls. diff --git a/tools/sdk/include/vfs/sys/dirent.h b/tools/sdk/include/vfs/sys/dirent.h new file mode 100644 index 00000000..57b5be5e --- /dev/null +++ b/tools/sdk/include/vfs/sys/dirent.h @@ -0,0 +1,55 @@ +// 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. + +#pragma once + +#include +#include + +/** + * This header file provides POSIX-compatible definitions of directory + * access functions and related data types. + * See http://pubs.opengroup.org/onlinepubs/7908799/xsh/dirent.h.html + * for reference. + */ + +/** + * @brief Opaque directory structure + */ +typedef struct { + uint16_t dd_vfs_idx; /*!< VFS index, not to be used by applications */ + uint16_t dd_rsv; /*!< field reserved for future extension */ + /* remaining fields are defined by VFS implementation */ +} DIR; + +/** + * @brief Directory entry structure + */ +struct dirent { + int d_ino; /*!< file number */ + uint8_t d_type; /*!< not defined in POSIX, but present in BSD and Linux */ +#define DT_UNKNOWN 0 +#define DT_REG 1 +#define DT_DIR 2 + char d_name[256]; /*!< zero-terminated file name */ +}; + +DIR* opendir(const char* name); +struct dirent* readdir(DIR* pdir); +long telldir(DIR* pdir); +void seekdir(DIR* pdir, long loc); +void rewinddir(DIR* pdir); +int closedir(DIR* pdir); +int readdir_r(DIR* pdir, struct dirent* entry, struct dirent** out_dirent); + diff --git a/tools/sdk/ld/esp32.common.ld b/tools/sdk/ld/esp32.common.ld index 09b76344..8cc3b5b2 100644 --- a/tools/sdk/ld/esp32.common.ld +++ b/tools/sdk/ld/esp32.common.ld @@ -19,9 +19,11 @@ SECTIONS */ .rtc.data : { + _rtc_data_start = ABSOLUTE(.); *(.rtc.data) *(.rtc.rodata) *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) + _rtc_data_end = ABSOLUTE(.); } > rtc_slow_seg /* RTC bss, from any source file named rtc_wake_stub*.c */ @@ -85,6 +87,26 @@ SECTIONS _iram_text_end = ABSOLUTE(.); } > iram0_0_seg + .dram0.data : + { + _data_start = ABSOLUTE(.); + KEEP(*(.data)) + KEEP(*(.data.*)) + KEEP(*(.gnu.linkonce.d.*)) + KEEP(*(.data1)) + KEEP(*(.sdata)) + KEEP(*(.sdata.*)) + KEEP(*(.gnu.linkonce.s.*)) + KEEP(*(.sdata2)) + KEEP(*(.sdata2.*)) + KEEP(*(.gnu.linkonce.s2.*)) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + *libesp32.a:panic.o(.rodata .rodata.*) + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + /* Shared RAM */ .dram0.bss (NOLOAD) : { @@ -106,26 +128,6 @@ SECTIONS *(COMMON) . = ALIGN (8); _bss_end = ABSOLUTE(.); - } >dram0_0_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - *(.dram1 .dram1.*) - *libesp32.a:panic.o(.rodata .rodata.*) - _data_end = ABSOLUTE(.); - . = ALIGN(4); _heap_start = ABSOLUTE(.); } >dram0_0_seg diff --git a/tools/sdk/ld/esp32.peripherals.ld b/tools/sdk/ld/esp32.peripherals.ld index 95aaadcb..8d8d4e8b 100644 --- a/tools/sdk/ld/esp32.peripherals.ld +++ b/tools/sdk/ld/esp32.peripherals.ld @@ -19,3 +19,4 @@ PROVIDE ( SPI3 = 0x3ff65000 ); PROVIDE ( I2C1 = 0x3ff67000 ); PROVIDE ( I2S1 = 0x3ff6D000 ); PROVIDE ( UART2 = 0x3ff6E000 ); +PROVIDE ( SDMMC = 0x3ff68000 ); diff --git a/tools/sdk/ld/esp32.rom.ld b/tools/sdk/ld/esp32.rom.ld index 6241ff84..7543fa42 100644 --- a/tools/sdk/ld/esp32.rom.ld +++ b/tools/sdk/ld/esp32.rom.ld @@ -87,9 +87,9 @@ PROVIDE ( _ctype_ = 0x3ff96354 ); PROVIDE ( __ctype_ptr__ = 0x3ff96350 ); PROVIDE ( __ctzdi2 = 0x4000ca64 ); PROVIDE ( __ctzsi2 = 0x4000c7f0 ); -PROVIDE ( _data_end = 0x4000d5c8 ); +PROVIDE ( _data_end_rom = 0x4000d5c8 ); PROVIDE ( _data_end_btdm_rom = 0x4000d4f8 ); -PROVIDE ( _data_start = 0x4000d4f8 ); +PROVIDE ( _data_start_rom = 0x4000d4f8 ); PROVIDE ( _data_start_btdm_rom = 0x4000d4f4 ); PROVIDE ( _data_start_btdm = 0x3ffae6e0); PROVIDE ( _data_end_btdm = 0x3ffaff10); @@ -202,7 +202,7 @@ PROVIDE ( ets_timer_init = 0x400084e8 ); PROVIDE ( ets_timer_setfn = 0x40008350 ); PROVIDE ( ets_unpack_flash_code = 0x40007018 ); PROVIDE ( ets_unpack_flash_code_legacy = 0x4000694c ); -PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); +PROVIDE ( ets_update_cpu_frequency_rom = 0x40008550 ); /* Updates g_ticks_per_us on the current CPU only; not on the other core */ PROVIDE ( ets_waiti0 = 0x400067d8 ); PROVIDE ( exc_cause_table = 0x3ff991d0 ); PROVIDE ( _exit_r = 0x4000bd28 ); @@ -1725,6 +1725,8 @@ PROVIDE ( xthal_memcpy = 0x4000c0bc ); PROVIDE ( xthal_set_ccompare = 0x4000c058 ); PROVIDE ( xthal_set_intclear = 0x4000c1ec ); PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); +PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 ); +PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 ); /* These functions are xtos-related (or call xtos-related functions) and do not play well with multicore FreeRTOS. Where needed, we provide alternatives that are multicore diff --git a/tools/sdk/lib/libapp_update.a b/tools/sdk/lib/libapp_update.a index 95efe756..69c92fb3 100644 Binary files a/tools/sdk/lib/libapp_update.a and b/tools/sdk/lib/libapp_update.a differ diff --git a/tools/sdk/lib/libbootloader_support.a b/tools/sdk/lib/libbootloader_support.a index b498f424..ae1035f0 100644 Binary files a/tools/sdk/lib/libbootloader_support.a and b/tools/sdk/lib/libbootloader_support.a differ diff --git a/tools/sdk/lib/libbt.a b/tools/sdk/lib/libbt.a index 2d7936f9..d1b81057 100644 Binary files a/tools/sdk/lib/libbt.a and b/tools/sdk/lib/libbt.a differ diff --git a/tools/sdk/lib/libbtdm_app.a b/tools/sdk/lib/libbtdm_app.a old mode 100755 new mode 100644 index af4f0dd9..76609852 Binary files a/tools/sdk/lib/libbtdm_app.a and b/tools/sdk/lib/libbtdm_app.a differ diff --git a/tools/sdk/lib/libc.a b/tools/sdk/lib/libc.a index 4377fa25..36a1cc60 100644 Binary files a/tools/sdk/lib/libc.a and b/tools/sdk/lib/libc.a differ diff --git a/tools/sdk/lib/libc_nano.a b/tools/sdk/lib/libc_nano.a index 2a99a9c4..9afd3798 100644 Binary files a/tools/sdk/lib/libc_nano.a and b/tools/sdk/lib/libc_nano.a differ diff --git a/tools/sdk/lib/libcoap.a b/tools/sdk/lib/libcoap.a new file mode 100644 index 00000000..71f7bd28 Binary files /dev/null and b/tools/sdk/lib/libcoap.a differ diff --git a/tools/sdk/lib/libcoexist.a b/tools/sdk/lib/libcoexist.a index d9bd0c12..68186c0c 100644 Binary files a/tools/sdk/lib/libcoexist.a and b/tools/sdk/lib/libcoexist.a differ diff --git a/tools/sdk/lib/libcore.a b/tools/sdk/lib/libcore.a index d944c0a7..52f64908 100644 Binary files a/tools/sdk/lib/libcore.a and b/tools/sdk/lib/libcore.a differ diff --git a/tools/sdk/lib/libcxx.a b/tools/sdk/lib/libcxx.a new file mode 100644 index 00000000..5afe9f5e Binary files /dev/null and b/tools/sdk/lib/libcxx.a differ diff --git a/tools/sdk/lib/libdriver.a b/tools/sdk/lib/libdriver.a index 642784b9..01e47d9a 100644 Binary files a/tools/sdk/lib/libdriver.a and b/tools/sdk/lib/libdriver.a differ diff --git a/tools/sdk/lib/libesp32.a b/tools/sdk/lib/libesp32.a index cb5d1ddf..1988be7c 100644 Binary files a/tools/sdk/lib/libesp32.a and b/tools/sdk/lib/libesp32.a differ diff --git a/tools/sdk/lib/libethernet.a b/tools/sdk/lib/libethernet.a index 01a9a57f..b6343148 100644 Binary files a/tools/sdk/lib/libethernet.a and b/tools/sdk/lib/libethernet.a differ diff --git a/tools/sdk/lib/libexpat.a b/tools/sdk/lib/libexpat.a index 7a28c057..63341f71 100644 Binary files a/tools/sdk/lib/libexpat.a and b/tools/sdk/lib/libexpat.a differ diff --git a/tools/sdk/lib/libfatfs.a b/tools/sdk/lib/libfatfs.a new file mode 100644 index 00000000..b542b7e1 Binary files /dev/null and b/tools/sdk/lib/libfatfs.a differ diff --git a/tools/sdk/lib/libfreertos.a b/tools/sdk/lib/libfreertos.a index 8bbc4ee7..2887e96c 100644 Binary files a/tools/sdk/lib/libfreertos.a and b/tools/sdk/lib/libfreertos.a differ diff --git a/tools/sdk/lib/libjson.a b/tools/sdk/lib/libjson.a index f1e05508..50896f99 100644 Binary files a/tools/sdk/lib/libjson.a and b/tools/sdk/lib/libjson.a differ diff --git a/tools/sdk/lib/liblog.a b/tools/sdk/lib/liblog.a index 9376a7cf..b313a39e 100644 Binary files a/tools/sdk/lib/liblog.a and b/tools/sdk/lib/liblog.a differ diff --git a/tools/sdk/lib/liblwip.a b/tools/sdk/lib/liblwip.a index 2d71df14..182d2292 100644 Binary files a/tools/sdk/lib/liblwip.a and b/tools/sdk/lib/liblwip.a differ diff --git a/tools/sdk/lib/libmbedtls.a b/tools/sdk/lib/libmbedtls.a index 67c10b56..8abed700 100644 Binary files a/tools/sdk/lib/libmbedtls.a and b/tools/sdk/lib/libmbedtls.a differ diff --git a/tools/sdk/lib/libmdns.a b/tools/sdk/lib/libmdns.a new file mode 100644 index 00000000..12d52e44 Binary files /dev/null and b/tools/sdk/lib/libmdns.a differ diff --git a/tools/sdk/lib/libmicro-ecc.a b/tools/sdk/lib/libmicro-ecc.a index e0ff4500..f3b6f4e9 100644 Binary files a/tools/sdk/lib/libmicro-ecc.a and b/tools/sdk/lib/libmicro-ecc.a differ diff --git a/tools/sdk/lib/libnet80211.a b/tools/sdk/lib/libnet80211.a index 4c8fcbc9..c18b4bc5 100644 Binary files a/tools/sdk/lib/libnet80211.a and b/tools/sdk/lib/libnet80211.a differ diff --git a/tools/sdk/lib/libnewlib.a b/tools/sdk/lib/libnewlib.a index 4a54ea66..37218aa9 100644 Binary files a/tools/sdk/lib/libnewlib.a and b/tools/sdk/lib/libnewlib.a differ diff --git a/tools/sdk/lib/libnghttp.a b/tools/sdk/lib/libnghttp.a index dcbb58ab..77702ba9 100644 Binary files a/tools/sdk/lib/libnghttp.a and b/tools/sdk/lib/libnghttp.a differ diff --git a/tools/sdk/lib/libnvs_flash.a b/tools/sdk/lib/libnvs_flash.a index 868b6915..cf08a428 100644 Binary files a/tools/sdk/lib/libnvs_flash.a and b/tools/sdk/lib/libnvs_flash.a differ diff --git a/tools/sdk/lib/libopenssl.a b/tools/sdk/lib/libopenssl.a index 19a0350a..1f321383 100644 Binary files a/tools/sdk/lib/libopenssl.a and b/tools/sdk/lib/libopenssl.a differ diff --git a/tools/sdk/lib/libpp.a b/tools/sdk/lib/libpp.a index 22e0c71e..b21285d5 100644 Binary files a/tools/sdk/lib/libpp.a and b/tools/sdk/lib/libpp.a differ diff --git a/tools/sdk/lib/libsdmmc.a b/tools/sdk/lib/libsdmmc.a new file mode 100644 index 00000000..22d0a743 Binary files /dev/null and b/tools/sdk/lib/libsdmmc.a differ diff --git a/tools/sdk/lib/libspi_flash.a b/tools/sdk/lib/libspi_flash.a index 9b0aa552..3a973601 100644 Binary files a/tools/sdk/lib/libspi_flash.a and b/tools/sdk/lib/libspi_flash.a differ diff --git a/tools/sdk/lib/libtcpip_adapter.a b/tools/sdk/lib/libtcpip_adapter.a index 1b4e4759..c5a5263b 100644 Binary files a/tools/sdk/lib/libtcpip_adapter.a and b/tools/sdk/lib/libtcpip_adapter.a differ diff --git a/tools/sdk/lib/libulp.a b/tools/sdk/lib/libulp.a index bb22da76..93b60a6c 100644 Binary files a/tools/sdk/lib/libulp.a and b/tools/sdk/lib/libulp.a differ diff --git a/tools/sdk/lib/libvfs.a b/tools/sdk/lib/libvfs.a index e0ff0888..c4a5c19e 100644 Binary files a/tools/sdk/lib/libvfs.a and b/tools/sdk/lib/libvfs.a differ diff --git a/tools/sdk/lib/libwpa.a b/tools/sdk/lib/libwpa.a index ff1fb9cc..5e646ba1 100644 Binary files a/tools/sdk/lib/libwpa.a and b/tools/sdk/lib/libwpa.a differ diff --git a/tools/sdk/lib/libwpa2.a b/tools/sdk/lib/libwpa2.a index 62a14060..aba4ac24 100644 Binary files a/tools/sdk/lib/libwpa2.a and b/tools/sdk/lib/libwpa2.a differ diff --git a/tools/sdk/lib/libwpa_supplicant.a b/tools/sdk/lib/libwpa_supplicant.a index 0707c447..2f07ebf9 100644 Binary files a/tools/sdk/lib/libwpa_supplicant.a and b/tools/sdk/lib/libwpa_supplicant.a differ diff --git a/tools/sdk/lib/libwps.a b/tools/sdk/lib/libwps.a index 1abd4689..ed8002c7 100644 Binary files a/tools/sdk/lib/libwps.a and b/tools/sdk/lib/libwps.a differ diff --git a/tools/sdk/lib/libxtensa-debug-module.a b/tools/sdk/lib/libxtensa-debug-module.a index a5ac9512..e20e662a 100644 Binary files a/tools/sdk/lib/libxtensa-debug-module.a and b/tools/sdk/lib/libxtensa-debug-module.a differ